Laboratorio di Sistemi Ereditarietà Java L'ereditarietà consente allo sviluppatore di riutilizzare il codice già scritto creando sottoclassi a partire da classi già definite. La sottoclasse eredita tutti gli attributi e tutti i metodi definiti dalla superclasse, ad eccezione di quelli che sono stati dichiarati private. Sono quindi ereditati tutti i membri con visibilità public indipendentemente dal package in cui si trovano le due classi e tutti i membri con visibilità package (cioè se sottoclasse e superclasse sono contenute nello stesso package). Se invece sottoclasse e superclasse appartengono a package (o sottopackage) differenti, allora la visibilità dei membri della superclasse deve essere protected se vogliamo garantire l'ereditarietà. La relazione tra la classe generale e la classe più specializzata prende il nome di relazione ISA (è un). La classe Studente può estendere la classe Persona. Infatti uno studente è una persona. In Java è presente un solo tipo di ereditarietà, detta ereditarietà singola, cioè ogni classe può avere al più una superclasse. Non è consentita, almeno in maniera diretta, la cosiddetta ereditarietà multipla. Vedremo comunque che in Java è consentita una certa forma di ereditarietà multipla mediante l'utilizzo delle interfacce (rimandiamo il lettore alla lettura dell'articolo sulle interfacce). Infatti vedremo che una classe può estenderne un'altra e implementare una o più interfacce. In uno degli esercizi trattati in classe, abbiamo considerato la relazione Punto-Cerchio e abbiamo interpretato il legame tra le due classi come una composizione. ereditarieta.pdf Pag. 1/7 Cozzetto © Laboratorio di Sistemi Ereditarietà Java Nessuno ci vietà però di vedere tale relazione come una relazione di tipo ISA (possiamo infatti interpretare il legame Punto-Cerchio affermando che un cerchio non è altro che un punto “dotato” di un raggio). Possiamo poi estendere la classe Cerchio introducendo la classe Cilindro. Segue codice delle 3 classi (e della classe Main di prova): /* * Punto.java */ // tutte le classi per semplicità sono contenute nello stesso package package geometriajavaapp; import java.util.Scanner; /** * * @author maurizio */ public class Punto { double x,y; /** Creates a new instance of Punto */ public Punto() { x=0; y=0; } public Punto(double x, double y) { this.x=x; this.y=y; } ereditarieta.pdf Pag. 2/7 Cozzetto © Laboratorio di Sistemi Ereditarietà Java public static double quadrato(double a) { return a*a; } public double distanza(Punto p) { return Math.sqrt(quadrato(p.x-x)+quadrato(p.y-y)); } public static Punto leggiPunto(String messaggio) { Scanner sc = new Scanner(System.in); System.out.println(messaggio); double x = sc.nextDouble(); double y = sc.nextDouble(); return new Punto(x,y); } @Override public String toString() { return "Coordinate del punto: ("+x+", "+y+")"; } public void stampaPunto() { System.out.println(toString()); } } // fine classe Punto /* * Cerchio.java */ package geometriajavaapp; /** * * @author maurizio */ public class Cerchio extends Punto { double r; // le due classi Punto e Cerchio si trovano nello stesso package /** Costruttore senza parametri * identifica il cerchio con centro l'origine * e raggio unitario */ public Cerchio() { // richiamo il costruttore della superclasse // senza parametri super(); r=1; } ereditarieta.pdf Pag. 3/7 Cozzetto © Laboratorio di Sistemi Ereditarietà Java /** Costruttore con un punto come parametro * identifica il cerchio con centro il punto c * e raggio unitario */ public Cerchio(Punto c) { // richiamo il costruttore della superclasse // con 2 parametri, le coordinate x e y del cerchio super(c.x, c.y); r=1; } /** Costruttore generale * identifica il cerchio con centro il punto c * e raggio r */ public Cerchio(Punto c, double r) { // richiamo del costruttore ... super(c.x, c.y); this.r=r; } /** Costruttore con due parametri * le coordinate x e y del centro * identifica il cerchio con centro il punto di * coordinate (x,y) e raggio unitario */ public Cerchio(double x, double y) { super(x,y); r=1; } /** Costruttore con 3 parametri * le coordinate x e y del centro e il raggio r * identifica il cerchio con centro il punto * di coordinate (x,y) e raggio r */ public Cerchio(double x, double y, double r) { super(x,y); this.r=r; } /** Costruttore con un solo parametro il raggio r * identifica il cerchio con centro l'origine * e raggio r assegnato */ public Cerchio(double r) { super(); this.r=r; } ereditarieta.pdf Pag. 4/7 Cozzetto © Laboratorio di Sistemi Ereditarietà Java public void stampaCerchio() { // richiamo del metodo stampaPunto della superclasse super.stampaPunto(); stampaRaggio(); } public void stampaCentro() { super.stampaPunto(); } public void stampaRaggio() { System.out.println("Raggio="+r); } public double superficie() { return Math.PI*r*r; } public void stampaSuperficie() { System.out.println("Superficie="+superficie()); } public double circonferenza() { return 2*Math.PI*r; } // imposto il centro public void setCentro(Punto c) { super.x=c.x; super.y=c.y; } // imposto il centro di coordinate x e y public void setCentro(double x, double y) { Punto p=new Punto(x,y); this.setCentro(p); } // restituisce il centro, un oggetto Punto public Punto getCentro() { return new Punto(super.x,super.y); } } // fine classe Cerchio ereditarieta.pdf Pag. 5/7 Cozzetto © Laboratorio di Sistemi Ereditarietà Java /* * Cilindro.java */ package geometriajavaapp; /** * * @author maurizio */ public class Cilindro extends Cerchio { double h; public Cilindro() { // costruttore senza argomenti della superclasse Cerchio super(); h=1; } public Cilindro(double x, double y, double r, double h) { // costruttore della superclasse Cerchio con 3 parametri super(x,y,r); this.h=h; } public Cilindro(Cerchio c, double h) { super(c); this.h=h; } // Eventuali altri costruttori // Overridding del metodo superficie della classe Cerchio @Override public double superficie() { return 2*super.superficie()+2*Math.PI*super.r*h; } public double volume() { return superficie()*h; } @Override public void stampaSuperficie() { System.out.println("Superficie="+superficie()); } public void stampaVolume() { System.out.println("Volume="+volume()); } ereditarieta.pdf Pag. 6/7 Cozzetto © Laboratorio di Sistemi Ereditarietà Java public void stampaCilindro() { super.stampaCerchio(); System.out.println("Altezza="+h); stampaSuperficie(); stampaVolume(); } } // fine classe Cilindro /* * Main.java */ package geometriajavaapp; /** * @author maurizio */ public class Main { public static void main(String[] args) { // creo un cerchio con centro l'origine e raggio 1 Cerchio c = new Cerchio(); c.stampaCerchio(); // verifico che il centro sia l'origine Punto p=c.getCentro(); c.stampaCentro(); // cambio le coordinate del centro del cerchio // lasciando invariato il raggio c.setCentro(5.6, 6.8); c.stampaCerchio(); // creo un cilindro con centro il // punto (1,1) con raggio 1 e altezza 1 Cilindro d = new Cilindro(1, 1, 1, 1); d.stampaCilindro(); // creo un altro cilindro Cilindro e = new Cilindro(new Cerchio(new Punto(1,1),1),1); // si tratta dello stesso cilindro costruito precedentemente e.stampaCilindro(); } } // fine classe Main ereditarieta.pdf Pag. 7/7 Cozzetto ©