Derivazione tra classi
Classe D derivata da B class B { //CLASSE BASE int x; void G() { x = x * 20; } } class D extends B { //CLASSE DERIVATA void H() { x = x * 10; } }
Principi fondamentali della derivazione – Principio 1 Tutte le proprietà definite per la classe base vengono implicitamente definite anche nella classe derivata …
Principi fondamentali della derivazione – Principio 1 … cioè vengono ereditate da quest’ultima. Ad esempio la classe D ha il campo dati int x; e la funzione void G();
Principi fondamentali della derivazione – Principio 2 La classe derivata può avere ulteriori proprietà … Ad esempio la classe D ha in più, rispetto alla classe base B, la funzione void H();
Principi fondamentali della derivazione – Principio 3 Ogni oggetto della classe derivata è anche un oggetto della classe base … … cioè si può usare un oggetto della classe derivata in ogni situazione/contesto in cui si può usare un oggetto della classe base
Principi fondamentali della derivazione – Principio 3 static void stampa(B bb) { System.out.println(bb.x); } … D d = new D(); d.G(); //OK stampa(d); //OK … la classe D è compatibile con la classe B.
Principi fondamentali della derivazione – Principio 4 Non è vero che un oggetto della classe base è anche un oggetto della classe derivata … … non è possibile usare un oggetto della classe base laddove si può usare un oggetto della classe derivata.
Principi fondamentali della derivazione – Principio 4 B b = new B(); b.H(); //NO: non ha il campo H() D d = b; //NO: B non è compatibile con D b = new D(); //OK D è compatibile con B
Gerarchie di classi: in profondità Una classe derivata può fungere da classe base per ulteriori derivazioni … class B {…} class D extends B {…} class E extends D {…}
Gerarchie di classi: in ampiezza Una classe può avere un numero qualsiasi di classi derivate … class B {…} class D extends B {…} class Dbis extends B {…}
Gerarchie di classi: esempio Dbis E Ogni classe ha solo una classe base… …no ereditarietà multipla in Java
Casting
Riferimenti di diverse classi possono denotare lo stesso oggetto class B {…} class D extends B { int x_d; } … D d = new D(); d.x_d = 10; B b = d; //OK b e d denotano lo stesso ogg. b.x_d = 20; //NO x_d non è un campo di B! //type checking statico
Casting per accedere ai campi della classe derivata class B {…} class D extends B { int x_d; } … D d = new D(); d.x_d = 10; B b = d; //OK b e d denotano lo stesso ogg. ((D)b).x_d = 20; //OK (D)b è un riferimento di tipo D
Il casting tra classi lungo lo stesso cammino in una gerarchia di derivazione è … … sempre sintatticamente corretto (non vengono mai rivelati errori di compilazione) … … ma è responsabilità del programmatore che sia anche semanticamente corretto …
Esempio class B {…} class D extends B { int x_d; } … B b = new B(); D d = (D)b; //OK a tempo di compilazione, ma … //NO a runtime (ClassCastException) d.x_d = 10; //NOTA: x_d non esiste nell’oggetto //denotato da d!
Livello di accesso protected
Una classe D derivata da un’altra classe B, anche se in un package diverso, ha una relazione speciale con quest’ultima… …non è un cliente qualsiasi di B in quanto vogliamo poter usare oggetti di D al posto dei quelli di B… …non coincide con B.
Per questo motivo può essere che B voglia mettere a disposizione di D dei campi che non sono a disposizione di clienti generici di B …per fare ciò si dicharano detti campi protected… …garantendo l’accesso ad essi alle classi derivate, ma bloccandone l’accesso ai clienti generici.
Costruttori delle classi derivate
Anche gli oggetti delle classi derivate sono creati chiamando un costruttore… …tale costruttore però deve inizializzare anche i campi dati ereditati… … alcuni dei quali sono inaccessibili dalla classe derivata (es. private)…
…per fare ciò Java richiede di invocare un costruttore della classe base nei costruttori della classe derivata… …mediante il costrutto super() che deve essere la prima istruzione eseguibile del corpo del costruttore della classe derivata.
Esempio EsempioCostuttori1.java
Qualora un costruttore della classe derivata non contiene l’invocazione esplicita di un costruttore … …viene invocato automaticamente il costruttore senza parametri… …se quest’ultimo non è presente viene generato un errore.
Esempio EsempioCostuttori2.java
Se una classe derivata non contiene costruttori … …Java ne fornisce automaticamente un costruttore standard senza parametri… …che invoca il costruttore senza parametri della classe base... …e lascia i campi dati della classe derivata al loro valore di default.
Esempio EsempioCostuttori3.java
Costrutto this() …da utilizzare in modo analogo a super()… …è un’invocazione esplicita ad un altro costruttore della stessa classe… …permette si riusare codice già scritto…
Esempio PersonaThis.java
Principi fondamentali della derivazione Principio 1: la classe derivata eredita le proprietà (campi) della classe base Principio 2: può avere ultriori proprietà Principo 3: è compatibile con la classe base Principio 4: ma non il viceversa