Conversioni
di tipo fra sottoclasse e superclasse
Può esserci la
necessità di memorizzare un riferimento di una sottoclasse
in un riferimento a superclasse.
Questo è possibile e avviene in modo automatico. Consideriamo :
- Sottoclasse extendes Superclasse
- Superclasse extendes Object (tutte le classi lo fanno)
SottoClasse ssc = new SottoClasse();
SuperClasse ss = new SuperClasse();
Object ogg = new Object();
ss = ssc;
ogg=ssc;
Abbiamo tre
riferimenti diversi che
vedono la stessa area di memoria :
L' esigenza nasce se si devono trattare in modo simile tutte le sottoclassi di una certa superclasse. consideriamo :
- Una superclasse
- Un insieme di sottoclassi
- Una classe "trattante" che riceve in ingresso una qualunque sottoclasse e esegue una certa operazione, compatibile con tutte le sottoclassi.
Si può pensare di aggiungere metodi con firma diversa per ogni classe oppure implementare il meccanismo descritto sopra :
- La classe trattante riceve sempre la superclasse e quindi non cambia mai
- Ogni sottoclasse ha un suo metodo particolare che implementa il suo comportamento
Un esempio semplice è:
public class SuperClasse {
public static void main(String[] args) {
SuperClasse sc = new SuperClasse();
SottoClasseA A = new SottoClasseA();
SottoClasseB B = new SottoClasseB();
SottoClasseC C = new SottoClasseC();
SottoClasseD D = new SottoClasseD();
metodozzo(sc);
sc
= A;
metodozzo(sc);
sc
= B;
metodozzo(sc);
sc
= C;
metodozzo(sc);
sc
= D;
metodozzo(sc);
}
public static void
metodozzo(SuperClasse sc) {
sc.stampaLettera();
}
public String
stampaLettera() {
System.out.println("0");
return "0";
}
}
class SottoClasseA extends SuperClasse {
public String stampaLettera() {
System.out.println("A");
return "A";
}
}
class SottoClasseB extends SuperClasse {
public String stampaLettera() {
System.out.println("B");
return "B";
}
}
class SottoClasseC extends SuperClasse {
public String stampaLettera() {
System.out.println("C");
return "C";
}
}
class SottoClasseD extends SuperClasse {
public String stampaLettera() {
System.out.println("D");
return "D";
}
}
Il flusso dal metodozzo rimane invariato. Ogni volta si passa una SuperClasse e poi a seconda dell'oggetto viene invocato il giusto metodo. In questo modo se domani qualcuno vuole aggiungere una sottoclasse nuova, basta che scriva un metodo stampaLettera e questa sottoclasse verrà trattata come le altre senza aggiungere codice.
Se invece si decide per la riscrittura dei metodi si avrebbe una cosa così:
public class SuperClasse {
public static void main(String[] args) {
SuperClasse sc = new SuperClasse();
SottoClasseA A = new SottoClasseA();
SottoClasseB B = new SottoClasseB();
SottoClasseC C = new SottoClasseC();
SottoClasseD D = new SottoClasseD();
metodozzo(sc);
sc
= A;
metodozzo(sc);
sc
= B;
metodozzo(sc);
sc
= C;
metodozzo(sc);
sc
= D;
metodozzo(sc);
}
public static void
metodozzo(SuperClasse sc) {
sc.stampaLettera();
}
public static void
metodozzo(SottoClasseA sc) {
sc.stampaLettera();
}
public static void
metodozzo(SottoClasseB sc) {
sc.stampaLettera();
}
public static void
metodozzo(SottoClasseC sc) {
sc.stampaLettera();
}
public static void
metodozzo(SottoClasseD sc) {
sc.stampaLettera();
}
public String
stampaLettera() {
System.out.println("0");
return "0";
}
}
class SottoClasseA extends SuperClasse {
public String stampaLettera() {
System.out.println("A");
return "A";
}
}
class SottoClasseB extends SuperClasse {
public String stampaLettera() {
System.out.println("B");
return "B";
}
}
class SottoClasseC extends SuperClasse {
public String stampaLettera() {
System.out.println("C");
return "C";
}
}
class SottoClasseD extends SuperClasse {
public String stampaLettera() {
System.out.println("D");
return "D";
}
}
Cioè per ogni sottoclasse il metodo metodozzo va riscritto! Oltre ad essere faticoso ricordarsi tutti i punti dove intervenire in caso di sottoclasse nuova si peggiora la manutenzione dello stesso metodo, perchè una eventuale modifica a metodozzo va riscritta per tutti i metodi!

Nessun commento:
Posta un commento