Mòdul 5

Pràctica 1: Herència. La biblioteca escolar sense herència
Tornar presentació tema
    Pràctica 1 Pràctica 2 Pràctica 3 Pràctica 4 Pràctica 5  
     
 

En aquest capítol aprendràs algunes característiques de Java que el fan un llenguatge extremadament potent i versàtil: les capacitats d'herència d'objectes. Aquests conceptes constitueixen el nucli del que entenem com a "orientació a objectes" del llenguatge.

 
     
  Tots els llenguatges de darrera generació estan equipats amb estratègies d'herència perquè s'ha demostrat que és un paradigma que fa molt productiu el procés de codificació i manteniment de programes. Així doncs, si vols estar al dia en llenguatges de programació, és pràcticament obligatori que tinguis una idea sobre el funcionament de l'herència. Allò que aprenguis en aquest apartat ho podràs aplicar després d'una forma molt aproximada en llenguatges com el C++, C#, Delphi, PHP o JavaScript. Cada llenguatge gestiona l'herència d'objectes de la seva forma, però la idea general és molt similar en tots els casos.  
     
  L'herència és una eina molt potent, que pot ser molt útil per a resoldre molts problemes de programació. Intenta no passar per alt els aprenentatges d'aquest capítol perquè és fonamental una bona planificació de l'herència per a fer el programes comprensibles, fàcils de mantenir i robustos.  
     
  Per a consolidar aquests conceptes treballaràs sobre un projecte de biblioteca escolar. En faràs una versió sense aproximació d'herència i, després, a la segona pràctica del mòdul, el modificaràs utilitzant l'herència. L'objectiu és que reflexionis sobre els avantatges que aporta aquest model de programació.  
     
  La biblioteca escolar  
 


La directora del teu institut ha descobert que ets un expert programador i t'encarrega l'elaboració del programari de gestió de la biblioteca escolar. En una anàlisi de les necessitats inicials arribes a la conclussió que has de crear una base de dades de dos tipus d'objectes: llibres i revistes. El programa consistirà en una eina capaç de mantenir registres de llibres i revistes (afegir, esborrar i actualitzar registres) i fer llistes dels continguts de la base de dades.

 
     
 

Com, de moment, encara no has après ha utilitzar un motor de dades amb les teves aplicacions, simularàs la base de dades amb llistes del tipus ArrayList on aniràs desant llibres i revistes. Tampoc completaràs en aquesta pràctica tot el procés d'actualització de dades, només donaràs al programa una funcionalitat mínima: la capacitat de llistar els objectes afegits a la base de dades.

 
     
  Sembla evident que el que has de fer, en primer lloc, és crear les classes de Java que representen els objectes que gestiona el programa de la biblioteca. Com has d'emmagatzemar llibres i revistes, crearàs una classe per als llibres i una altra per a les revistes. Observa la seva representació en forma de diagrama:  
     
   
 
Diagrama UML dels objectes Llibre i Revista
 
     
 
El llibre l'ha escrit un autor, té un títol, el va publicar una editorial en una data determinada, té un número concret de pàgines, el classifiquem dins d'un gènere i li assignem un registre en el sistema de classificació decimal, etc.
 
     
  Les revistes són lleugerament diferents. Per exemple, una dada fonamental és el número de la revista (aquesta informació no existeix en els llibres) o no té un autor identificable (quan aquesta informació és fonamental en un llibre). Molts camps, però, són idèntics als llibres i a les revistes (la classificació decimal, el títol, els comentaris, l'editorial que fa la publicació, etc.)  
     
 

Cadascuna de les dues classes tindrà el seu constructor corresponent i un sol mètode: imprimir(), amb la funció d'escriure a la cònsola el contingut d'alguns camps de la classe.

 

Anem a codificar aquestes dues primeres peces de l'aplicació. Obre el BlueJ i crea un nou projecte a la teva carpeta de projectes. Posa-li de nom "Biblioteca". Crea dues classes noves.

 
     
  La primera és la classe Llibre. Crea-la i afegeix-li aquest codi:  
/**
* @author Angel Solans
* @version 13/04/2005
*/
public class Llibre {

    private String autor;
    private String titol;
    private String editorial;
    private String data;
    private int pagines;
    private String genere;
    private String classificacioDecimal;
    private String departament;
    private String comentaris;

    public Llibre(String autor, String titol,
        String editorial, String data) {
        this.autor=autor;
        this.titol=titol;
        this.editorial=editorial;
        this.data=data;
    }

    public void imprimir() {
        System.out.println("(Llibre) "+titol+", "+
        autor+", ed. "+editorial);
        System.out.println(" -> "+comentaris);
    }
}

 
 
La segona és la classe Revista. Crea-la i afegeix:
 
/**
* @author Angel Solans
* @version 13/04/2005
*/

public class Revista {

    private String numero;
    private String titol;
    private String editorial;
    private String data;
    private int pagines;
    private String classificacioDecimal;
    private String comentaris;
    private String departament;
    private String genere;

    public Revista(String titol, String numero, String data ) {
        this.titol=titol;
        this.numero=numero;
        this.data=data;
    }

    public void imprimir() {
        System.out.println("(Revista) "+titol+
         ", nº "+numero+", "+data);
        System.out.println(" -> "+comentaris);
    }

}

 
     
 

Es tracta de dues classes molt senzilles, formades exclusivament pels camps, un contructor i un mètode.

 
     
 

Observa la visibilitat dels camps a les dues classes. Són del tipus private, és a dir, que no són visibles des de l'exterior de la pròpia classe:

    ...
    private String numero;
    private String titol;
    ...

Això ho hem fet expressament, amb la intenció de protegir l'accés a la informació que conté la classe. L'assignació d'informació s'ha de fer mitjançant els constructors o amb mètodes creats adhoc i l'accés a les dades només es podrà fer si en creem mètodes adequats.

Recorda sempre que aquesta estratègia d'encapsulament d'informació és pràcticament obligatòria en programació Java.

 
     

Ara, abans de continuar codificant, intenta contestar les següents qüestions relatives a les classes que acabes de crear:

1.- Podries dir quins camps s'inicialitzen en el constructor de la classe Llibre? I de la classe Revista?

2.- Hi ha alguns camps que no poden ser inicialitzats de cap manera. Quins són a la classe Llibre? I a la classe Revista?

3.- Escriu un mètode que serveixi per a canviar el valor del camp comentaris de la classe Llibre.

4.- Escriu en mètode que serveixi per a obtenir el valor actual del camp comentaris de la classe Llibre.

5.- Perquè creus que aquests dos mètodes que acabes d'escriure són coneguts amb el nom de mètodes getter i setter?

6.- Observa els constructor d'ambdues classes. En aquesta expressió 
this.titol=titol; quin significat té la paraula this?

 

 
     
 

Ara que ja tens les classes dels objectes de la biblioteca, hauràs d'escriure el programa que farà funcionar la biblioteca. Has de crear la base de dades i la classe que es comuniqui amb la base de dades.

 
     
Escriuràs una nova classe amb el nom de Biblioteca que contindrà la base de dades i els mètodes de gestió de la biblioteca. Crea-la i afegeix aquest codi:  
     
import java.util.ArrayList;
import java.util.Iterator;

/**
* @author Angel Solans
* @version 13-04-2005
*/

public class Biblioteca {
    private ArrayList llibres;
    private ArrayList revistes;

    public Biblioteca() {
        llibres = new ArrayList();
        revistes = new ArrayList();
    }

    public void afegeixLlibre(Llibre llibre) {
        llibres.add(llibre);
    }

    public void afegeixRevista(Revista revista) {
        revistes.add(revista);
    }

    public void imprimir() {
        for(Iterator iterador = llibres.iterator();
         iterador.hasNext();) {
            Llibre llibre = (Llibre)iterador.next();
            llibre.imprimir();
            System.out.println("--------------------");
        }
        for(Iterator iterador = revistes.iterator();
         iterador.hasNext();)     {
            Revista revista = (Revista)iterador.next();
            revista.imprimir();
            System.out.println("------------------");
        }
    }


}

 
     
 

El cor de la base de dades són els dos objectes ArrayList que desen la llista de llibres i revistes. Com a camps o atributs de la classe, seguim la convenció de crear-los com a objectes privats de la classe:

public class Biblioteca {
    private ArrayList llibres;
    private ArrayList revistes;
    ...
}

La feina del constructor de la classe és la inicialització de les dues llistes:

public class Biblioteca {
    ...
    public Biblioteca() {
        llibres = new ArrayList();
        revistes = new ArrayList();
    }
    ...
}

Els mètodes de la classe són elementals:

a) dos mètodes ens permeten afegir objectes Llibre i Revista a la llista:

public class Biblioteca {
    ...
    public void afegeixLlibre(Llibre llibre) {
        llibres.add(llibre);
    }
    ...
}

b) un mètode que genera la llista d'objectes enregistrats a la base de dades:

public class Biblioteca {
    ...
    public void imprimir() {
        for(Iterator iterador = llibres.iterator();
         iterador.hasNext();) {
            Llibre llibre = (Llibre)iterador.next();
            llibre.imprimir();
            System.out.println("--------------------");
        }
        for(Iterator iterador = revistes.iterator();
         iterador.hasNext();)     {
            Revista revista = (Revista)iterador.next();
            revista.imprimir();
            System.out.println("------------------");
        }
    }
    ...
}

Per a fer el llistat utilitzes dos objectes de la classe Iterator. Un Iterator serveix per a resseguir seqüencialment els elements continguts en una llista. El primer iterador et servirà la llista d'objectes Llibre el segon la llista d'elements Revista. Per a cada pas de l'iterador es fa una crida al mètode imprimir() que genera una sortida a la cònsola amb les dades del llibre o la revista.

 
     

Posa a prova el funcionament del programa: enregistra i compil·la totes les classes.

Quan tinguis el codi a punt,

1) Crea dues instàncies d'objectes Llibre i dues instàncies d'objectes Revista. Omple els camps del constructor amb llibres i revistes que tinguis a mà:

 
 
 
 
Creant una instància de Revista
 
 

2) Crea una instància d'objecte Biblioteca.

3) Afegeix a la base de dades els quatres objectes que acabes de crear tot executant els mètodes afegeixLlibre() i afegeixRevista(). Recordes com es fa per passar una instància d'objecte com a paràmetre en un mètode?. En el moment que crides el mètode afegeixLlibre() escrius a la caixa el nom de la instància de llibre que has creat abans. Si has creat la instància llibre1, escriuras llibre1 a la caixa:

 
 
 
 
Tot passant una instància d'objecte com a paràmetre.
 
 
4) Executa el mètode imprimir(). T'ha de donar una sortida similar a aquesta:

 
 
 
     
 

L'aplicació ja està funcionant!.

 
     
 

No és molt funcional però, com veuràs a la pràctica següent, és força il·lustrativa dels inconvenients de planificar un programa sense utilització de l'herència.

A la segona pràctica del mòdul refaràs el programa incorporant-li algunes bones estratègies d'herència.

 
     

Contesta les següents qüestions

7.- El mètode imprimir() genera un llistat en el que s'escriu al final de cada llibre o revista la paraula null. Quin és el significat exacte d'aquest terme? Com hauries de modificar el valor o estat del camp comentaris per a evitar que aparegués en el llistat?

8.- A més de les ArrayList en mòduls anteriors has estudiat les matrius i els vectors com a models alternatius d'agrupació de dades.
Escriu un programa Biblioteca2 que en lloc d'ArrayList utilitzi vectors i matrius per a emmagatzemar les dades del fons de la biblioteca. Modifica el mètode imprimir() de tal forma que el cicle d'impressió no el faci un Iterator sinó un bucle for(;;) {}.
Quins avantatges i inconvenients tenen cadascuna de les dues aproximacions?

 

 
     
 

 

 

Tornar al principi