subtype polymorphism. interfacce e subtype polimorfismo tipi, sottotipi e conversioni di tipo...
TRANSCRIPT
![Page 1: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/1.jpg)
Subtype Polymorphism
![Page 2: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/2.jpg)
• Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch
![Page 3: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/3.jpg)
Conversioni di tipo
• Variabile: locazione con un tipo associato Tipo della variabile determinato dal compilatore
guardando la dichiarazione Una variabile di tipo reference contiene un riferimento
ad un oggetto
• Oggetto: istanza di una classe Tipo dell’oggetto: la classe che lo crea Determinato a run time
• Una variabile può assumere come valori riferimenti ad oggetti di classi diverse
Continua…
![Page 4: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/4.jpg)
Conversioni di tipo
• È possibile assegnare un riferimento di tipo classe ad una variabile di tipo interfaccia purchè la classe implementi l’interfaccia
BankAccount account = new BankAccount(10000);Measurable x = account; // OK
Coin dime = new Coin(0.1, "dime");Measurable y = dime; // OK
Continua…
![Page 5: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/5.jpg)
Conversioni di tipo
• La conversione è lecita solo in determinate situazioni
• Problema: Rectangle non implementa Measurable
Measurable x = new Rectangle(5, 10, 20, 30); // ERRORE
![Page 6: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/6.jpg)
Subtyping
• Subtyping (<:) Una relazione che permette di decidere quando è
legittimo convertire un tipo riferimento in un altro
• Chi decide cosa/quando è legittimo? il compilatore!
• Per il momento la regola è:
Continua…
T1 <: T2 sse T1 è una classe, T2 è una interfaccia T1 implementa T2.
![Page 7: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/7.jpg)
Subtyping
• Principio di sostituibilità Un riferimento di un sottotipo può essere usato
ovunque ci si aspetti un riferimento di un supertipo
• Le regole di sottotipo devono garantire la correttezza del principio di sostituibilità
Continua…
![Page 8: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/8.jpg)
Subtyping
• La regola C <: I se C implementa I
• Principio di sostituibilità un riferimento di tipo C può sempre essere usato dove
si attende un riferimento di tipo I
• E’ ragionevole perché se C implementa I , C definisce public tutti i metodi
dichiarati da I Quindi tutti le invocazioni di metodo possibili per I sono
supportate da C
Continua…
![Page 9: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/9.jpg)
Subtyping e regole di typing
• Regola di assegnamento Un riferimento di tipo T1 si puo sempre assegnare ad una variabile
di tipo T2 sse T1 <: T2 Un riferimento di tipo classe può sempre essere assegnato ad una
variabile di tipo interfaccia (se la classe implementa l’interfaccia)
• Regola di passaggio di parametri Un riferimento di tipo T1 si puo sempre passare per un parametro
di tipo T2 sse T1 <: T2 Un riferimento di tipo classe può sempre essere passato per un
parametro di tipo interfaccia (se la classe implementa l’interfaccia)
![Page 10: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/10.jpg)
Domanda
• Data l’implementazione generica della classe DataSet, che oggetti possiamo passare come argomento per x ?
public class DataSet { public void add(Measurable x) { ... }
... }
![Page 11: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/11.jpg)
Risposta
• Qualunque istanza di una una classe che implementa Measurable
![Page 12: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/12.jpg)
Polimorfismo – dynamic dispatch
• Una variabile di tipo interfaccia ha sempre come valore un riferimento di una classe che implementa l’interfaccia
Continua…
Measurable x;x = new BankAccount(10000);x = new Coin(0.1, "dime");
![Page 13: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/13.jpg)
Polimorfismo – dynamic dispatch
• Possiamo invocare ognuno dei metodi dell’interfaccia:
• Quale metodo invoca?
double m = x.getMeasure();
![Page 14: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/14.jpg)
Polimorfismo – dynamic dispatch
• Dipende dal riferimento corrente memorizzato nella variabile
• Se x riferisce un BankAccount, invoca il metodo BankAccount.getMeasure()
• Se x riferisce un Coin, invoca il metodo Coin.getMeasure()
• Polimorfismo (molte forme): il comportamento varia, e dipende dal tipo dinamico
della variabile
Continua…
![Page 15: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/15.jpg)
Domande
5. È impossibile costruire un oggetto di tipo Measurable.Perché?
6. Perché invece é possibile dichiarare una variabile di tipo Measurable?
![Page 16: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/16.jpg)
Risposte
5. Measurable è una interfaccia. Le interfacce non hanno campi o implementazione di metodo.
6. Perché Measurable è un tipo: la variabile non riferirà mai una istanza di Measurable, (le interfacce non hanno istanze) ma piuttosto oggetto di una qualche classe che implementa l’interfaccia Measurable.
Continua…
![Page 17: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/17.jpg)
• Costruiamo una applicazione per disegnare un insieme di forme geometriche contenute in una componente grafico: definiamo GWin, una classe che descrive un
contenitore di forme geometriche disegnate mediante una invocazione del metodo paint()
per esemplificare, consideriamo due tipi di forme: Car e Smiley
Ancora un esempio
![Page 18: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/18.jpg)
Forme grafiche
class Car{ . . . public void draw(Graphics2D g) { // Istruzioni per il disegno . . . }} class Smiley
{ . . . public void draw(Graphics2D g) { // Istruzioni per il disegno . . . }}
![Page 19: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/19.jpg)
• Un contenitore di Cars e Smileys
GWin
/** Una finestra che contiene un insieme Cars e Smileys */ class GWin { /** Disegna tutte le forme di questo component */ public void paint(){ /* disegna su g */ } /**
Componente grafica su cui disegnare */
private Graphics2D g; }
![Page 20: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/20.jpg)
Domanda
• Che struttura utilizziamo per memorizzare le forme contenute nella GWin?
• Come definiamo il metodo paint() in modo che disegni tutte le forme della componente?
![Page 21: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/21.jpg)
Risposte
• definiamo una nuova interfaccia: Shape
• Ridefiniamo le classi Car e Smiley in modo che implementino Shape
• Memorizziamo gli oggetti della componente in una ArrayList<Shape>
interface Shape { void draw(Graphics2D g); }
![Page 22: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/22.jpg)
Car e Smiley implementano Shape
class Car implements Shape
{ . . . public void draw(Graphics2D g) { // Istruzioni per il disegno . . . }} class Smiley implements Shape
{ . . . public void draw(Graphics2D g) { // Istruzioni per il disegno . . . }}
![Page 23: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/23.jpg)
Mantiene una ArrayList<Shape>
GWin
class GWin { private Graphics2D g; private ArrayList<Shape> shapes; // crea una GWin con un insieme di forme public GWin(Shape... shapes) { Graphics2D g = new Graphics2D();
this.shapes = new ArrayList<Shape>(); for (Shape s:shapes) this.shapes.add(s); } // disegna tutte le componenti della GWin public void paint() {
for (Shape s:shapes) s.draw(g); } }
![Page 24: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/24.jpg)
Diagramma delle Classi
Car
GWin
Smiley
Shape
Car
![Page 25: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/25.jpg)
So long, for today
![Page 26: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/26.jpg)
Polimorfismo – dynamic dispatch
• Dynamic dispatch: Il metodo da invocare per rispondere ad un
messaggio è deciso a tempo di esecuzione
![Page 27: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/27.jpg)
Dynamic dispatch in GWin
class GWin { . . . private ArrayList<Shape> shapes; . . . public void paint() {
// disegna tutte le componenti della GWin // il metodo invocato effettivamente da ogni
// messaggio s.draw(g) dipende dalla classe // di cui s è istanza ed è deciso a runtime
for (Shape s:shapes) s.draw(g); } . . . . }
![Page 28: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/28.jpg)
Dynamic dispatch vs overloading
• Dynamic dispatch: Il metodo da invocare per rispondere ad un
messaggio è deciso a tempo di esecuzione
• Notiamo bene Il metodo da invocare è deciso a runtime il compilatore decide se esiste un metodo da invocare
• Overloading: Nel caso esista più di un metodo, il compilatore
decide staticamente il tipo del metodo da invocare
![Page 29: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/29.jpg)
Dynamic dispatch vs overloading
interface I { public String m(boolean b); public String m(double d); } class A implements I { public String m(boolean b) { return “A.m(boolean)”; } public String m(double d) { return “A.m(double)”; } }
class B implements I { public String m(boolean b) { return “B.m(boolean)”; } public String m(double d) { return “B.m(double)”; } }
![Page 30: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/30.jpg)
Dynamic dispatch vs overloading
class Client { public void static show(I x) { // tipo del metodo invocato = m(boolean) // deciso dal compilatore staticamente // metodo invocato deciso dinamicamente // in funzione del tipo dell’argomento // passato per x
System.out.println( x.m(false) ); } }
![Page 31: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/31.jpg)
Domanda
• Che cosa hanno in comune i meccanismi di overloading e di dynamic dispatch? In cosa sono diversi?
![Page 32: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/32.jpg)
• Entrambi i meccanismi contribuiscono a decidono quale metodo eseguire in risposta ad un messaggio, ma• Nell’overloading scelta è relativa al tipo del metodo,
ed è fatta in compilazione guardando il tipo dei parametri
• Nel dynamic dispatch la scelta è relativa al corpo del metodo, ed è fatta in esecuzione guardando il tipo dell’oggetto che riceve il messaggio
Risposta
![Page 33: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/33.jpg)
Subtyping e sostituibilità
• Principio di sostituibilità Un riferimento di un sottotipo può essere usato
ovunque ci si aspetti un riferimento di un supertipo
• Le regole di sottotipo garantiscono la correttezza del principio di sostituibilità Tutti i metodi del supertipo devono essere
implementati dal sottotipo Il sottotipi può avere anche altri metodi
Continua…
![Page 34: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/34.jpg)
Subtyping e perdita di informazione
• Principio di sostituibilità Un riferimento di un sottotipo può essere usato
ovunque ci si aspetti un riferimento di un supertipo
• Può causare perdita di informazione nel contesto in cui ci aspettiamo il supertipo, non
possiamo usare solo I metodi del supertipo perdiamo la possibilità di utilizzare gli eventuali metodi
aggiuntivi del sottotipo
Continua…
![Page 35: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/35.jpg)
Car e Smiley implementano Shape
class Smiley implements Shape
{ . . .public void draw(Graphics2D g){ . . . }public String mood() {. . . }
}
class Car implements Shape
{ . . .public void draw(Graphics2D g){ . . . }public String brand() {. . . }
}
![Page 36: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/36.jpg)
Subtyping e perdita di informazione
• Consideriamo
public static void printBrand(List<Shape> l)
{ for (Shape s : l)
// stampa la marca di tutte le macchine di l
// ???
}
Continua…
![Page 37: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/37.jpg)
Subtyping e perdita di informazione
• Certamente non possiamo fare così …
public static void printBrand(List<Shape> l)
{ for (Shape s : l)
// stampa la marca di tutte le macchine di l
System.out.println( s.brand() ); // TYPE ERROR!
}
Continua…
![Page 38: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/38.jpg)
Cast
• Permette di modificare il tipo associato ad una espressione
• Un cast è permesso dal compilatore solo se applica conversioni tra tipi compatibili
• Compatibili = sottotipi (per il momento)
• Anche quando permesso dal compilatore, un cast può causare errore a run time
• Se s non è un Car errore a run time
Continua…
((Car)s).brand()
![Page 39: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/39.jpg)
Cast
• Tipo statico e tipo dinamico di una variabile tipo statico: quello dichiarato tipo dinamico: il tipo del riferimento assegnato alla
variabile
• (T)var causa errore in compilazione
se T non è compatibile con il tipo statico di var in esecuzione (ClassCastException)
se T non è compatibile con il tipo dinamico di var
Continua…
![Page 40: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/40.jpg)
Cast
• OK: Car sottotipo di Shape
• Compila correttamente il tipo dichiarato di s è Shape Car e Shape sono compatibili
• Esegue correttamente s è un Car (il tipo dinamico di s è Car)
Shape s = new Car();
Continua…
Car c = (Car) s
![Page 41: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/41.jpg)
Cast
• OK: Car sottotipo di Shape
• Compila correttamente il tipo dichiarato di s è Shape Smiley e Shape sono compatibili
• Errore a run time s non è uno Smiley
Shape s = new Car();
Continua…
Smiley c = (Smiley) s
![Page 42: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/42.jpg)
Cast
• Attenzione anche qui …
public static void printBrand(List<Shape> l)
{ for (Shape s : l)
// ClassCastException se s instance of Smiley
System.out.println( ((Car)s.)brand() );
}
Continua…
![Page 43: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/43.jpg)
instanceof
• Permette di determinare il tipo dinamico di una variabile
• Quindi permette di evitare errori in esecuzione
• Esegue correttamente, perchè x è sicuramente un T
x istanceof T è true solo se x ha tipo dinamico T
if (x instanceof T) return (T) x
![Page 44: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/44.jpg)
Cast
• Questo, finalmente, è corretto
public static void printBrand(List<Shape> l)
{ for (Shape s : l)
if (s instanceof Car)
System.out.println( ((Car)s.)brand() );
}
![Page 45: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/45.jpg)
Domanda
• E se volessimo disegnare solo le Shapes che sono Cars?
![Page 46: Subtype Polymorphism. Interfacce e subtype polimorfismo Tipi, sottotipi e conversioni di tipo Polimorfismo e dinamic dispatch](https://reader034.vdocumenti.com/reader034/viewer/2022052618/5542eb59497959361e8c427d/html5/thumbnails/46.jpg)
Risposta
// disegna tutte le Cars della GWin
public void paint(){ for (Shape c:shapes)
if (c instanceof Car) c.draw(g); }