Ereditarietà

La classe Rettangolo possiede le proprietà colore e misure dei lati, e possiede i metodi per leggere i valori delle proprietà. Inoltre possiede le stesse proprietà di una Figura.

Rettangolo
base
altezza
getBase()
getAltezza
———
Figura
colore
getColore()



La classe Cerchio possiede le proprietà colore e misura del Raggio, e possiede i metodi per leggere i valori delle proprietà.

L'associazione tra le classi si rappresenta mediante una linea a tratto intero che collega le due classi.

Cerchio
raggio
getRaggio
————
Figura
colore
getColore()



Le due classi hanno in comune la proprietà colore e il metodo per leggere il colore. Si crea una classe Figura che racchiude tutte le proprietà e i metodi delle figure geometriche e la si incorpora nelle classi delle figure geometriche, aggiungendo a queste solo le proprietà e i metodi propri della figura geometrica.


il file Figura.java
class Figura{
  private String colore;
  Figura(String col) {
    colore = col;
  }
  String getColore() {
    return colore;
  }
}

il file Rettangolo.java
Il costruttore della classe Rettangolo richiama prima il costruttore della classe base e poi assegna i valori alle proprietà della classe.
class Rettangolo {
  private double altezza;
  private double base;
  private Figura figura;
  Rettangolo (String col, double alt, double bas) {
    figura = new Figura(col);
    altezza = alt;
    base = bas;
  }
  String getColore() {
    return figura.getColore();
  }
}

il file Cerchio.java
Il costruttore della classe Cerchio richiama prima il costruttore della classe base e poi assegna il valore alla proprietà della classe.
class Cerchio {
  private double raggio;
  private Figura figuraCer;
  Cerchio (String col, double rag) {
    figuraCer = new Figura(col);
    raggio = rag;
  }
  String getColore() {
    return figuraCer.getColore();
  }
}

Utilizzo delle classi:

class Geometria {
  public static void main(String args[ ]) {
    Rettangolo rett = new Rettangolo("Rosso", 10, 20);
    Cerchio cerchio = new Cerchio("Blu", 15);
 
    System.out.println(rett + ": " + rett.getColore());
    System.out.println(cerchio + ": " + cerchio.getColore());
  }
}

Secondo Esercizio
Ereditarietà

La programmazione orientata agli oggetti introduce l'ereditarietà: dopo aver definito una classe discendente, i metodi della classe antenato vengono ereditati ma, volendo, è anche possibile ridefinirli. Per ridefinire il metodo ereditato, è sufficiente definire un nuovo metodo con lo stesso nome di quello ereditato, ma con un corpo diverso e (se necessario) un diverso insieme di parametri.

L'ereditarietà si rappresenta graficamente tramite una freccia con il triangolino vuoto che parte dalla classe derivata e giunge alla classe base.

Figura
colore
getColore()
getArea()

Rettangolo
base
altezza
getBase()
getAltezza()
getArea()
Cerchio
 
raggio
 
getRaggio()
getArea()

Le classi rappresentate nel diagramma vengono dichiarate nel modo seguente.

Figura.java
class Figura{
   private String colore;
   Figura(String col) {
      colore = col;
   }
  String getColore() {
       return colore;
   }
}

Rettangolo.java

la classe eredita i metodi e le proprietà della classe base specificando, nella dichiarazione della classe, il termine extends. Inoltre il costruttore della classe base viene richiamto con il metodo super, perchè la classe Figura non è incorporata, come oggetto, nelle classi Rettangolo e Cerchio.

class Rettangolo extends Figura {
   private double altezza;
   private double base;
   Rettangolo (String col, double alt,
			double bas) {
	super(col);
	altezza = alt;
	base = bas;
   }
   double getArea() {
      return altezza * base;
   }
}

Cerchio.java
class Cerchio extends Figura {
   private double raggio;
   Cerchio (String col, double rag) {
      super(col);
      raggio = rag;
   }
   double getArea() {
      return raggio *  raggio * 3.14;
   }
}

Utilizzo delle classi:

class Geometria {
  public static void main(String args[ ]) {
    Rettangolo rett = new Rettangolo("Rosso", 10, 20);
    Cerchio cerchio = new Cerchio("Blu", 15);
 
    System.out.println(rett + "- Area: " + rett.getArea());
    System.out.println(cerchio + "- Area: " + cerchio.getArea());
  }
}


Terzo Esercizio

Collegamento dinamico
Di una figura geometrica se ne può calcolare l'area, quindi il metodo getArea() viene assegnato alla classe base, ma viene ridefinito nelle classi derivate.


il file figura.java la classe Figura definisce il costruttore, il metodo per leggere il colore e il metodo per calcolare l'area.
class Figura{
  private String colore;
  Figura(String col) {
    colore = col;
  }
  String getColore() {
    return colore;
  }
  double getArea() {
    return 0;
  }
}

Si vede subito che il metodo getArea() della classe Figura non può essere definito in forma generale. Lo si dichiara abstract. Anche la classe diventa abstract.

Tutte le sottoclassi devono fornire la definizione del metodo per non essere anch'esse astratte

abstract class Figura {
  private String colore;
  Figura(String col) {
    colore = col;
  }
  String getColore() {
    return colore;
  }
  public String toString() {
    return "sono una figura";
  }
  abstract double getArea();
}

il file Rettangolo.java
La classe Rettangolo ridefinisce il metodo getArea() della classe base.
In questa nuova versione della classe si mostra un altro metodo per richiamare il costruttore della classe base.
class Rettangolo extends Figura {
  private double altezza;
  private double base;
  Rettangolo (String col, double alt, double bas) {
	super(col);
	altezza = alt;
	base = bas;
  }
  double getArea() {
    return altezza * base;
  }
}

il file Cerchio.java
La classe Cerchio ridefinisce il metodo getArea() della classe base.
In questa nuova versione della classe si mostra un altro metodo per richiamare il costruttore della classe base.
class Cerchio extends Figura {
  private double raggio;
  private Figura figuraCer;
  Cerchio (String col, double rag) {
    super(col);
    raggio = rag;
  }
  String getColore() {
    return figuraCer.getColore();
  }
  double getArea() {
    return raggio *  raggio * 3.14;
  }
  public String toString() {
    return "Figura: Cerchio. ";
  }
}




Uso delle classi

Le classi vengono usate dichiarando delle istanze in una classe contenente il metodo main()

class Geometria {
  public static void main(String args[ ]) {
    Rettangolo rett = new Rettangolo("Rosso", 10, 20);
    Cerchio cerchio = new Cerchio("blu", 15);
 
    System.out.println(rett + "- Area: " + rett.getArea());
    System.out.println(cerchio + "- Area: " + cerchio.getArea());
  }
}

Quarto Esercizio

Un'immagine può essere considerata come un insieme di figure geometriche

Ogni figura che compone l'immagine possiede un metodo per stamparsi. Il metodo stampa richiama il metodo stampati di ogni figura che compone l'immagine.

Nell'esempio l'array è dimensionato per contenere 10 figure geometriche. Ogni elemento dell'array, tramite il metodo addFigura(), memorizza il riferimento alla figura.

class Immagine {
  Figura figure[] = new Figura[10];
  int contatore = 0;
  void addFigura(Figura newFig) {
    figure[contatore++] = newFig;
  }
  void stampa() {
    for (int i = 0; i < contatore; i++) 
      figure[i].stampati();
  }
}

La classe Figura deve dichiarare un altro metodo astratto (che verrà ridefinito nelle classi derivate):

abstract void stampati();
Le classi derivate devono specializzare il metodo. Nella classe Rettangolo:
void stampati() {
      System.out.println("rettangolo" + getColore());
   }

Nella classe Cerchio:

void stampati() {
      System.out.println("cerchio " + getColore());
   }
Uso della classe:
class Geometria {
  public static void main ( String args[ ]) {
    Immagine immagine = new Immagine();
    immagine.addFigura(new Rettangolo("verde", 10,20));
    immagine.addFigura(new Cerchio("rosso", 15));
    immagine.stampa();
  }
}