|
|||||||||||||||||
![]() |
|||||||||||||||||
Pràctica |
![]() |
Exercicis
|
|||||||||||||||
Objectes i classes (II) | |||||
Les classes: | |||||
|
|||||
![]() |
Les classes són les mares dels objectes i són omnipresents en el llenguatge. S'han de conèixer els seus mecanismes en profunditat si es vol programar amb seguretat. Possiblement el que més sorprèn als programadors procedents d'altres llenguatges és l'absolut encapsulament de tots els processos del programa en una o més classes. Si procedim de C/C++ i anem a escriure un programa Java, segurament buscarem el lloc on posar una variable global a tot el programa, independent de les classes: doncs no, no el trobarem. Tot va a dins de l'àmbit d'alguna classe, ni que sigui en una classe genèrica per a tot el programa. Comencem per estudiar la carcassa de les classes de Java: Una classe té dues parts: la pròpia declaració de la classe i el cos, que n'és el contingut. Quan declarem una classe li assignem un nom, decidim quina és la seva classe mare (o superclasse) i si la nova classe implementa interfícies (vegeu la pràctica 4) . En el cas que no especifiquem cap classe mare, la nostra classe no quedarà sola: serà filla de la classe java.lang.Object, la mare de totes les classes. Aquestes són sintaxis possibles: Una classe molt simple, que no fa res i es filla directa de la classe java.lang.Object:
Una classe que és filla
de la classe laclasseMare:
Una classe filla
de laclasseMare i
que implementa
unainterficie i unaaltrainterficie:
Les classes filles hereten les variables i mètodes de les seves mares. Tot el que sap fer una classe mare, ho pot fer una classe filla (la filla encara pot fer més coses, perquè podem ampliar les seves capacitats). També sap fer les coses de la classe àvia i així anar pujant fins arribar a la classe java.lang.Object. Això, explicat d'aquesta forma, sembla simple, però no ho és: hi ha tota una casuística, que haurem d'aprendre, de mètodes i variables visibles o no a les altres classes, mètodes que canvien de contingut quan passen a les classes filles, etc. El cos de les classes conté les declaracions i inicialitzacions dels membres de la classe, siguin mètodes, variables de classe o variables d'instància i la descripció de la feina que fan els mètodes. |
||||
Diferents tipus de classes | |||||
No totes les classes són iguals ni tenen el mateix comportament. Què podem fer si ens interessa que una classe no pugui tenir fills? I si volem que una classe sigui visible fora del paquet? I si ens interessa crear prototipus a l'estil de C++? Per resoldre aquestes situacions, Java ens permet definir les nostres classes en diferents categories:
|
|||||
Diferents tipus de variables | |||||
Una variable és efectiva entre les dues claus ("{" i "}") on ha estat creada. Si escrivim una variable al començament de la classe, a l'exterior dels mètodes, estem definint una variable membre, visible per a tots els mètodes. Si la variable ésa l'interior d'un cert mètode, es tracta d'una variable local de mètode i no es veu més enllà d'aquest mètode. Les variables locals poden tenir el
mateix nom que les variables membre.
Per exemple, aquesta i és correcta:
Hem declarat dos enters (int) amb el nom "i". La primera i val 1000 i és una variable membre. La segona val 200 i és una variable local. Quan el compilador troba una i en el mètode unNombre() pensa que fa referència a la variable local. Que farem si des del mètode volem treballar amb la variable membre? Ens referirem a ella amb el terme this.nomvariable: |
|||||
![]() |
|
||||
Quin nombre creieu que ens retornarà aquest programa, 1000 o 666?. Si modifiquem return this.i del mètode unNombre() per return i, quin nombre retorna el programa? Al començament de la pràctica hem fet dues divisions fonamentals de variables, les variables d'instància i les variables de classe. Quan es crea un objecte, també es creen les seves variables d'instància corresponents. En canvi, quan es crea una variable de classe, sempre hi ha en memòria una sola còpia de la variable, que és compartida per tots els objectes de la classe. Per definir una variable de classe només
ens cal donar-li l'atribut static:
Aquesta variable la podem utilitzar
des de qualsevol instància:
En aquest cas, ens serviria per a controlar quants vídeos hem prestat des que hem iniciat el programa. Cada vegada que fem un préstec incrementem en una unitat la variable de classe prestatsAvui. Aquesta variable tindrà el mateix valor per a totes les instàncies de gestioVideos que corrin a la mateixa Màquina Virtual. Podem accedir al valor de les variables de classe sense necessitat de crear una instància de la classe. En el nostre exemple, podríem saber l'estat de la variable prestatsAvui escrivint gestioVideos.prestatsAvui des de qualsevol mètode que accedeixi al paquet, sense inicialitzar gestioVideos. Aquesta característica també la comparteixen els mètodes de classe. |
|||||
![]() |
No existeix cap llei escrita de Java
que prohibeixi accedir a les variables públiques
d'instància a les nostres classes:
degut a això hi són. De totes maneres és recomanable
crear les nostres variables d'instància
com a privades i fer-ne un accés
encapsulat a través de mètodes
getter i setter.
De fet, algunes de les tecnologies de Java
més importants (els Java Beans
i els Enterprise Java Beans) gairebé
ens obliguen a accedir a les variables
seguint aquest model. En lloc d'una classe
com aquesta:
hauríem de fer una classe com
aquesta:
Per a cadascuna de les variables, un dels mètodes public ens serveix per modificar el valor de la variable i l'altre per a obtenir-lo. L'increment de codi queda compensat per l'estandardització: moltes APIs de Java esperen accedir a les variables de les classes d'aquesta forma. |
||||
![]() |
Com que aquest és un model pràcticament universal, gairebé tots els IDEs incorporen utilitats per a encapsular variables automàticament. JCreator també ho incorpora, però només en la versió professional (de pagament). | ||||
Diferents tipus de mètodes | |||||
![]() |
Al mòdul 2 hem
après la forma i funcionament bàsics dels mètodes,
i través d'aquest apartat en veurem les implicacions des de la
programació orientada a objectes.
|
||||
![]() |
Escriviu aquest programa: | ||||
|
|||||
Quan el compilareu us donarà error. No podeu accedir a la variable d'instància especies_animals! Comenteu la declaració i la utilització de la variable i torneu a compilar el programa: ara anirà bé. Això vol dir que els mètodes de classe no poden accedir de cap forma a les variables d'instància? Sí, hi ha truc: podem aprofitar una de les característiques divertides de Java: una classe pot crear a dins seu instàncies de si mateixa! Per accedir a les variables d'instància des d'un mètode static hem de crear una instància de la pròpia classe dins del mètode. Així: |
|||||
|
|||||
|
|||||
![]() |
|||||