Mòdul 2   

Pràctica 2: Un Objecte de Java per dins    
Tornar presentació tema
    Pràctica 1 Pràctica 2 Pràctica 3 Pràctica 4 Pràctica 5 Pràctica 6  
<
     
 

L'objectiu d'aquesta pràctica és l'estudi d'una classe de Java a partir de l'anàlisi detallada del seu codi font. Aprendràs a identificar, entendre i escriure una classe senzilla de Java amb els seus camps, constructors i mètodes.

 
     
  Les peces d'un objecte de Java  
     
 

Fes un nou cop d'ull al programa perquè ara l'hauràs d'analitzar ben a fons. Has de tenir en compte en aquesta lectura que les línies que comencen amb * o amb // no són estrictament codi del programa sinó aclariments per fer-lo més entenedor quan el llegiu les persones que l'estudieu; més avall ja s'explica amb detall.

 
 
 

/**
* Gestor del nostre telèfon mòbil.
*
* @author Angel Solans
* @version 07.01.2004
*/
public class Mobil {
    // Camps per indicar el nostre número de telèfon,
    // el saldo existent a la nostra targeta
    // i el preu per cada pas o unitat de temps de trucada
    private int numero = 630010203;
    private int saldo;   
    private int preu;

    /**
    * Crea un telefon mòbil. Inicialment posa el saldo

    * a 350 i el preu a 2.
    */
    public Mobil() {
        saldo = 350;
        preu = 2;
    }

    /**
    * Incrementa el saldo de la targeta en la
    * quantitat que triem
    */
    public void carrega(int quantitat) {
        saldo+=quantitat;
    }

    /**
    * Fa una trucada del número de passos que triem.
    * Decrementa el nostre saldo en funció del preu
    * de cada pas
    */
    public void truca(int passos) {
        saldo-=(passos*preu);
    }

    /**
    * Retorna el nostre número de telèfon
    */
    public int getNumero() {
        return numero;
    }

    /**
    * Retorna el saldo restant a la targeta
    */
    public int getSaldo() {
        return saldo;
    }

    /**
    * Canvia el preu de cada pas
    */
    public void setPreu(int preu) {
        this.preu = preu;
    }

    /**
    * Retorna el preu de cada pas
    */
    public int getPreu() {
        return preu;
    }

    /**
    * Imprimeix el nostre saldo. Per la feina de la
    * consulta, ens resta una unitat
    */
    public void printSaldo() {
        saldo-=1;
        System.out.println("El vostre saldo és de "+saldo);
        System.out.println("moltes gràcies per la consulta");
    }

}

 
     
  La definició d'una classe  
 


Tot i què el nostre humil programa no pot fer encara massa coses, conté els principals elements estructurals d'una classe de Java. Ara en faràs la dissecció.

El mínim que necessites per a que una classe de Java funcioni és un nom. Per a posar nom i crear classes has de seguir la sintaxi següent :

 
  public class Mobil {
    aquí el contingut de la classe
}
 
 


Més endavant descobriràs perquè en alguns llocs posem public i en altres private. De moment en tens prou sabent que...

  • les classes es bategen amb public class seguit del nom que has triat per la classe
  • a continuació obres i tanques claus { }
  • tot el que escrius entre aquesta parella de claus és el contingut de la classe.

Dins la classe has d'escriure els tres components essencials d'una classe de Java: els camps, els constructors i els mètodes:

  • Els camps o variables d'instància serveixen per a desar informació d'ús per a la classe. Nombres, cadenes de text o altres objectes... qualsevol informació que puguis necessitar per al funcionament de la classe. Els valors dels camps es poden fer servir en tots i cada un dels mètodes de la classe, per tant, són un bon lloc per a desar informació compartida.

  • Els constructors contenen sentències que s'executen en el mateix moment que es crea un objecte de la classe. El constructor és, doncs, el primer fragment de codi que s'executa un cop la màquina de Java ha creat l'objecte. Són útils per a inicialitzar els camps o executar mètodes en els primers instants de vida d'un objecte.

  • Els mètodes contenen les instruccions de totes les feines que una classe sap fer. Són la musculatura i el cervell de la classe.

 

Java és molt flexible pel que fa a l'ordre en què estan escrits els camps, els constructors i els mètodes d'una classe. No és un error de sintaxi posar, per exemple, primer els mètodes que els constructors. Tot i així, els programadors mantenen convencions:

  • Escriureu sempre primer els camps, desprès els constructors i, finalment, els mètodes.

D'aquesta forma, quan passis la teva classe a un altre programador, la podrà llegir amb facilitat.

 
     
  Els camps (o variables d'instància)  
     
 
Qualsevol objecte necessita valors per a funcionar. Els nostres mòbils necessiten disposar d'un preu de la trucada i un saldo per a gestionar la nostra despesa telefònica. Observa aquest fragment de la classe Mobil :

 
 

public class Mobil {
    private int numero = 630010203;
    private int saldo;
    private int preu;

    Aquí la resta del contingut de la classe
}

 

El camp numero desa el número del nostre telèfon. Observa que escrivim private int numero i immediatament després fem l'assignació de valor (= 630010203). Més endavant estudiaràs perquè fem privats els camps de les classes.

Com que el número de telèfon és sempre un número enter, el definim del tipus int, enter. Si tingués decimals el podríem definir del tipus float o del tipus double. Si fos una cadena de text, el definiríem com a String. Poc a poc aniràs descobrint la quantitat immensa de tipus que pot arribar a tenir Java.

Els dos camps següents saldo i preu contenen respectivament el saldo de la targeta i el preu de cada pas de trucada. Els definim també del tipus int. Observa que en aquest cas només els creem i no n'assignem cap valor. Si no ho fem nosaltres, Java els donarà un valor per defecte, el 0.

 

  • El procés d'assignació significa que al camp o variable d'instància numero li donem el valor 630010203. Es fa posant un signe d'igualtat = (per exemple la que ja hem vist, numero = 630010203)
  • Els noms de camp s'escriuen sempre amb la inicial en minúscula: preu i saldo són correctes, Preu i Saldo serien incorrectes.
  • Els camps de tipus int s'inicialitzen per defecte amb el valor 0.
 
  Ara volem afegir al mòbil la capacitat de comptar el número total de trucades que hem fet des que l'hem creat.  
     
  • Ens posem a l'editor de codi del (recordeu-ho, doble clic al rectangle que representa la classe Mobil) i afegim, per sota del camp preu un nou camp amb el nom trucades. Ha de quedar exactament així:
 
 
public class Mobil {
    ...
    private int preu;
    private int trucades;
    ...
}
 
     
 
  • Has de tenir en compte aquestes recomanacions:
    • respecta sempre la indentació de les línies amb les sentències de Java; aquest costum fa el codi més fàcil de llegir.
    • adona't que les línies de les sentències acaben amb un punt i coma; en canvi no hi va punt i coma després de les claus { }
 
 
  • Un cop escrit el codi, fes Classe | Desar o bé Ctrl-S per a desar les modificacions al programa.

  • Seguidament pica sobre el botó Compilar. (Aquest pas és imprescindible, no te'l deixis!).

  • Comprova que has fet bé l'ampliació de la classe: crea un nou objecte o instància de la classe Mobil i fes doble-clic sobre ell. T'ha d'aparéixer un nou camp amb el nom de trucades. Observa: Quin és el valor inicial del camp trucades?

Ara torna a obrir l'editor de la classe Mobil i observa el text escrit sobre cadascuna de les definicions de camp: es tracta de comentaris, que serveixen per a fer aclaridor el contingut dels programes a una lector humà tot i que no tenen cap efecte en el propi programa:

 
 


public class Mobil {  
    // Camps per indicar el nostre número de telèfon,
    // el saldo existent a la nostra targeta
    // i el preu per cada pas o unitat de temps de trucada
    private int numero = 630010203;
    private int saldo;   
    private int preu;
    ...
}

 
     

Per a comentar una línia o una part de línia utilitzareu el símbol //.

  • El compilador de Java ignora tot el que estigui escrit entre aquest símbol i el final de línia.
  • Per a comentar un bloc d'una o vàries línies utilitzareu la sintaxi
       /*
       * comentari
       * comentari
       */

    o bé
       /**
       * comentari
       * comentari
       */

    El compilador de Java ignora tot el que hi hagi a l'interior d'aquest bloc.
 
 
Per acabar aquesta secció, feu un comentari d'una línia (//) explicant per a que serveix el camp trucades.

 
     
  Els constructors  
     
 

T'has fixat en què cada vegada que creem un objecte o instància de la classe mobil el saldo inicial és de 350 unitats monetàries? O que el preu de cada pas és de 2 unitats? Aquesta informació que un objecte sap des que el creem, la hi passem a través dels constructors.

  • Un constructor és un procediment especial que s'executa immediatament després que es crea un objecte i que serveix per a fer qualsevol tasca d'apertura que necessitem.

Observa aquest fragment de codi de la classe mòbil:

 
 

public class Mobil() {
    aquí els camps

    public Mobil() {
        saldo = 350;
        preu = 2;
    }

    aquí els mètodes
}

 
     
  El fragment que hem deixat és un constructor de la classe Mobil. Fixa't bé a veure si descobreixes què té d'especial la sintaxi d'un constructor:
  • El nom. Un constructor porta el mateix nom de la classe. La classe es diu Mobil. El constructor també .
  • El tipus. Els constructors no són de cap tipus, al contrari que els camps i els mètodes. Fixa't com després de l'atribut public no hem escrit res més que el nom de la classe, Mobil.

Si observes el codi que hi ha a l'interior del constructor veuràs la manera com assignem valor als camps saldo i preu.

Una classe pot tenir més d'un constructor. Imagina que necessitem crear dos tipus de telèfons: uns que es creen per defecte amb les 350 unitats monetàries i d'altres en què s'ha de decidir en el moment de l'activació quin és el seu saldo inicial. Per a atendre aquest segon cas, podem crear un constructor especial. Fem-ho.

 
     

Obre el i edita la classe Mobil. Immediatament per sota del primer constructor, escriu el codi d'aquest segon constructor:

 
     
 
public
Mobil(int saldoInicial) {
    saldo = saldoInicial;
    preu = 2;
}
 
     
 

Abans de continuar, intenta trobar la diferència amb el constructor original: continuem sense posar nom ni tipus, però hem afegit entre els parèntesis del constructor un paràmetre, un enter que es diu saldoInicial. Aquest terme és nou i molt important a la programació: paràmetre. Te l'expliquem en la següent pràctica, ara mira l'aspecte que té i el que fa.

  • Intenta crear un nou objecte Mobil clicant amb el botó dret del ratolí sobre la caixa de la classe. A la finestra emergent, el ens deixa triar entre dues formes de crear el nou objecte: new Mobil() i new Mobil(saldoInicial). Tria aquesta segona opció. Immediatament, el programa t'obliga a donar un saldo inicial per al nou telèfon amb una finestra com aquesta:
 
 
 
 
Figura 1. Creació d'un objecte de la classe mobil amb el segon constructor.
 
     
 
  • Dóna el valor de saldo inicial que t'interessi i clica a Accepta.

  • Situa't dins la instància de la classe (el nou objecte que has creat amb aquest constructor) i executa el mètode getSaldo(). Ens retorna el valor de saldo inicial assignat al constructor.
 
     
  Els mètodes  
 


Tot allò que una classe sap fer, ho té escrit en els seus mètodes. Els mètodes són l'autèntic cor i motor d'una classe. Quines coses sap fer el teu programa de control del mòbil? Sap carregar-se, sap imprimir o contestar a consultes sobre el saldo disponible,etc. I ho sap perquè té les instruccions per a fer cada tasca en els seus mètodes.

Analitza aquest codi:

 
  public class Mobil() {

    aquí els camps

    aquí els constructors

    public void carrega(int quantitat)
    public void truca(int passos)
    public int getNumero()
    public int getSaldo()
    public void setPreu(int preu)
    public int getPreu()
    public void printSaldo()
}
 
     
 


Observa la sintaxi de la capçalera dels diferents mètodes de la classe Mobil (ara hem eliminat el cos dels mètodes, tot el que va entre { } després de la capçalera, per a fer més fàcil la lectura).

Si has estat trastejant amb objectes d'aquesta classe ja saps el que fa cadascun d'ells. Ens interessa que et fixis en les diferències i similituds que hi ha en la seva sintaxi:

  • tots els mètodes estan definits amb l'atribut public, però la següent paraula, el tipus, varia en cada cas (uns mètodes són int i altres void).
  • A més, alguns dels mètodes tenen paràmetres d'entrada (expressats entre paréntesis, per exemple (int quantitat)) i d'altres no (tenen uns parèntesis buits ()) . Revisem com funciona tot això:
 
     
  Les parts d'un mètode  
     
 

Els mètodes tenen capçalera i cos, com els constructors o les classes. En la capçalera hi posem el nom del mètode, el tipus d'informació que retorna el tipus d'informació que li hem d'entrar per a poder funcionar. En el cos del mètode es codifica la feina del mètode.

Això és una capçalera:

 
     
 
public void carrega(int quantitat)

 
     
  i això és el cos del mètode carrega:
 
     
  {
        saldo+=quantitat;
}

 
 


És on es fa la feina del mètode. En aquest cas, quina feina ha de fer el mètode? Hem de sumar al nostre saldo el valor de la quantitat entrada mitjançant el mètode carrega. Disposem del camp saldo on emmagatzamem el nostre saldo en cada moment. Hem d'assignar un valor a aquest camp depenent del valor que ja té.

  • La instrucció més general en els llenguatges de programació per fer aquesta tasca és:
             saldo = saldo + quantitat;
    que vol dir que es calcula la suma dels valors emmagatzemats a les variables saldo i quantitat i el resultat s'emmagatzema com a nou valor de la variable saldo.
  • Tot i que la formulació anterior és ben correcta, Java disposa d'un operador += que permet escriure breument la instrucció anterior.
                      saldo += quantitat;
    és equivalent a
             saldo = saldo + quantitat;
  • També disposem de l'operador -=, que té un funcionament similar pero amb la resta, en lloc de la suma. Per exemple
             saldo -= (passos*preu);
    és equivalent a
             saldo = saldo - (passos*preu);
    i és la instrucció que fem servir per descomptar del nostre saldo el preu d'una trucada.
  • I encara hem de considerar dues possibilitats més:
    variable++
    que equival a variable = variable+1
    i
    variable-- que equival a variable = variable-1

L' operador -= té un funcionament similar però amb la resta, en lloc de la suma.

 
  El significat de la capçalera: mètodes void o amb tipus  
     
 

Ara imagina't un mètode com si fos una caixa fosca que no ens deixa veure el que hi ha al seu interior o com si fos una peça del teu ordinador, que la saps muntar, saps quina feina fa, però no saps com funciona internament. Només veus la capçalera.

En moltes ocasions, només sabràs d'un mètode la informació que et dóna la seva capçalera. Per això has d'aprende a llegir-la correctament.

 
 

El mètode retorna valors? Aquesta és la primera qüestió que has d'aprendre a contestar per a un mètode de Java: ens retorna un valor o només fa una feina interna a la classe?

Això és molt fàcil de llegir en una capçalera: els mètodes que per se no retornen cap valor porten l'atribut void.

 

 
  A) Mètodes amb tipus    
     
 

Habitualment voldrem que alguns mètodes serveixin per contestar-nos i passar-nos informació d'algun tipus o altre relatiu al valor actual d'alguna característica de la instància o objecte que estem analitzant. Quan a la capçalera d'un mètode trobes un tipus de dada (int, String, boolean) i no la partícula void això vol dir que el mètode ens retorna informació.

Revisa aquest mètode:

 
     
 
    public int getSaldo() {
        return saldo;
    }

 
     
 
Recordeu què fa? Ens diu quin és el saldo que ens resta al mòbil. Crideu-lo des del i observeu que obtenim una resposta
sobre un camp associat a l'objecte. Aquesta:

 
 
 
 
Figura 2. Un mètode amb tipus ens respon un nombre enter (int)
 
     
 

La finestra que s'ha obert et retorna un número enter (int) amb el valor del teu saldo. Fixa't que a la capçalera del mètode tenim definit el mètode com a int a diferència dels mètodes amb void que comentarem més avall.

  • Els mètodes de Java poden retornar qualsevol tipus de dada. Els més freqüents són el tipus int, String o boolean, però no existeix cap límit. Com que el programadors de Java, com ja estudiaràs, poden inventar-se els tipus de dades que vulguin, els mètodes poden retornar qualsevol cosa.
 
     
  Endevines el significat de la paraula reservada return en el cos del mètode? És tracta del valor de retorn del mètode. En els mètodes que retornen algun valor, hem de posar obligatòriament un return. En canvi en els mètodes void, veurem que no hi apareix return perquè no retornen automàticament cap valor; en cas de voler fer sortir informació com un text en pantalla o d'alguna altra manera haurem de fer servir les sentències adequades en els mètodes void.  
     

Tots els mètodes que retornen algun valor han de tenir en el seu cos un return que contingui el valor de retorn.

 
     
  B) Mètodes void    
     
 

A diferència dels anteriors, sempre que et trobis amb un void a la capçalera d'un mètode has de pensar que el mètode treballarà però que el seu objectiu no és donar-te el valor d'un camp o variable simplement pel fet de cridar-lo.

Revisa aquest mètode:

 
     
 
    public void truca(int passos) {
        saldo-=(passos*preu);
    }
 
     
 

Recordes el què fa? Ens descompta del saldo del mòbil una quantitat de diners perquè hem estat fent una trucada. Crida'l des del . Observa que, en activar-lo i un cop hem entrat el número de passos, el mètode no ens diu res. Ha modificat el saldo però no ens dóna el nou valor de la variable. Això passa sempre així amb els mètodes void.

 
     
  Tanmateix, veuràs en pràctiques següents que en els mètodes void s'hi poden incloure sentències que fabriquen altres tipus de sortides o respostes per a l'usuari o usuària del programa com és ara missatges, indicacions, resultats complexos,... que podem fer que s'imprimeixin en una finestra auxiliar  
     
  Una proposta final    
     
 

Per acabar la pràctica afegirm un mètode a la nostra classe. La idea és crear un mètode que retorni un valor enter amb el contingut del camp trucades que hem creat més amunt.

Naturalment, rpimer de tot haurem de fer una feina que encara no havíem incorporat al codi de la classe Mobil. Has de modificar el mètode truca perquè s'incrementi en una unitat el camp trucades cada cop que utilitzem el telèfon. És a dir, que per cada trucada que simulis has de fer trucades = trucades + 1 o si t'estimes més abreujar, trucades++.

I ara, imagines com ha de ser la capçalera del mètode que t'havíem proposat? Retorna algun valor o no? Necessita algun paràmetre per a funcionar? És un mètode molt senzill, té aquest aspecte:

 
     
   
   public int getTrucades() {
        return trucades;
    }
 
     

Obre l'editor de codi la classe i afegeix aquest mètode (vigila no posar-lo per error en el cos d'un altre mètode!). Enregistra els canvis amb l'opció de menú Classe|Desar o amb Ctrl-S i després recorda't de compilar.

Tot seguit crea un objecte nou de la classe i executa el mètode getTrucades(). Has d'obtenir, de moment, el resultat següent:

 
     
 
 
 
Figura 3. Valor inicial de retorn del mètode getTrucades().
 
 
 
  Ara fes algunes trucades amb el mètode truca i després torna a executar getTrucades(). Ha funcionat?