Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf ·...

80
Interfacce e Polimorfismo

Transcript of Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf ·...

Page 1: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Interfacce e Polimorfismo

Page 2: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Interfacce

• Dichiarazioni di tipi riferimento che descrivono oggetti in modo astratto

• Specificano solo le firme dei metodi tralasciando tutti gli aspetti di implementazione

Page 3: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Interfacce

interface Poly { public Poly somma (Poly p);

public Poly derivata();

public int grado();

public boolean equals (Poly p);

public double coefficient(int degree);

}

Page 4: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Interfacce

interface Collection<E> { public void add(E element);

public void remove(E element);

public boolean find(E element);

. . .

}

Page 5: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Classi implementano Interfacce

• La keyword implements indica che una classe implementa una interfaccia

class TreeSet<E> implements Collection<E>

{ ... }

class ArrayPoly implements Poly{ ... }

Page 6: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Classi implementano Interfacce

• Una classe che implementa una interfaccia deve implementare tutti i metodi dell’interfaccia

• Tutti I metodi dell’interfaccia devono essere dichiarati public nella classe

• Nulla vieta che la classe dichiari altri metodi oltre quelli dell’interfaccia che implementa

Page 7: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Classi implementano Interfacce• Una interfaccia può essere implementata da più

classi

class ListPoly implements Poly

{ ... }

class ArrayPoly implements Poly { ... }

Page 8: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Classi implementano Interfacce• Una interfaccia può essere implementata da più

classi

class TreeSet<E> implements Collection<E>

{ ... }

class HashMap<E> implements Collection<E>{ ... }

Page 9: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Conversioni di tipo

• Una interfaccia “rappresenta” tutte le classi che la implementano

• Il tipo interfaccia si può associare a tutti gli oggetti delle classi che la implementano

Continua…

Page 10: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Conversioni di tipo

• Possiamo assegnare un riferimento di tipo classe ad una variabile di tipo interfaccia purchè la classe implementi l’interfaccia

Collection<Double> c = new TreeSet<Double>();

Collection<Double> d = new HashMap<Double>();

Poly p = new ArrayPoly();

Poly q = new ListPoly();

Continua…

Page 11: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Conversioni di tipo

• La conversione è lecita solo in determinate situazioni

• Problema: TreeSet<Double>() non implementa Poly

Poly x = new TreeSet<Double>(); // ERRORE

Page 12: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Conversioni di Tipo

• Sottotipo (<:)– La relazione che permette di decidere quando è lecito

convertire un tipo riferimento in un altro – Per il momento diciamo

• Principio di sostituibilità– Ovunque ci si aspetti un riferimento di un tipo è lecito

utilizzare un rifetimento di un sottotipo

Continua…

S <: T sse ● S è una classe, T è una interfaccia ● S implementa T.

Page 13: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Conversioni di Tipo

• Assumiamo S <: T

• Regola di assegnamento– Un riferimento di tipo S si puo sempre assegnare ad una variabile

di tipo T – Un riferimento di tipo classe può sempre essere assegnato ad

una variabile di tipo interfaccia che la classe implementa

• Regola di passaggio di parametri– Un riferimento di tipo S si puo sempre passare per un parametro

di tipo T– Un riferimento di tipo classe può sempre essere passato per un

parametro di tipo interfaccia che la classe implementa

Page 14: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Conversioni di Tipo

• Le conversioni abilitate dalla regola

C <: I sse C implementa I

sono “corrette” – garantiscono che le proprietà che valgono

utilizzando valori di tipo I valgono usando valori di tipo C

• Dimostrazione intuitiva: – Se C implementa I , C deve definire tutti i metodi

dichiarati da I (e dichiararli public)– Quindi tutti le invocazioni di metodo ammesse da I

trovano effettivamente un metodo definito in C Continua…

Page 15: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Polimorfismo – dynamic dispatch

• Le regole di conversione di tipo garantiscono che una variabile di tipo interfaccia ha sempre come valore un riferimento di una classe che implementa l’interfaccia

• Se una interfaccia è implementata da più classi, il tipo dei valori legati alla variabile può cambiare

Continua…

Poly p;p = new ListPoly(...);p = new ArrayPoly(...);

Page 16: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Polimorfismo – dynamic dispatch

• Possiamo invocare ognuno dei metodi dell’interfaccia:

• Quale metodo invoca?

int g = p.grado();

Page 17: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Polimorfismo – dynamic dispatch

• Se p riferisce un ListPoly, invoca il metodo ListPoly.grado()

• Se p riferisce un ArrayPoly, invoca il metodo ArrayPoly.grado();

• Polimorfismo (molte forme): – il metodo invocato dipende dipende dal tipo del

riferimento legato alla variabile

Continua…

int g = p.grado();

Page 18: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

• 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: Quadrato e Cerchio

Esempio

Page 19: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Forme grafiche

class Quadrato{ . . . public void draw(Graphics2D g) { // Istruzioni per il disegno . . . }} class Cerchio

{ . . . public void draw(Graphics2D g) { // Istruzioni per il disegno . . . }}

Page 20: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

• Un contenitore di Quadrati e Cerchi

GWin

/** Una finestra che contiene Quadrati e Cerchi */ class GWin { /** Disegna tutte le forme di questo component */ public void paint(){ /* disegna su g */ } /**

Componente grafica su cui disegnare */ private Graphics2D g; }

Page 21: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

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 22: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Risposte

• definiamo una nuova interfaccia: Shape

• Ridefiniamo le classi Quadrato e Cerchio in modo che implementino Shape

• Memorizziamo gli oggetti della componente in una ArrayList<Shape>

interface Shape { void draw(Graphics2D g); }

Page 23: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Shapes

class Quadrato implements Shape

{ . . . public void draw(Graphics2D g) { // Istruzioni per il disegno . . . }}

class Cerchio implements Shape

{ . . . public void draw(Graphics2D g) { // Istruzioni per il disegno . . . }}

Page 24: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

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 25: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Diagramma delle Classi

Car

GWin

Cerchio

Shape

Quadrato

Page 26: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Ancora Interfacce

Page 27: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Esempio

• Definiamo una classe DataSet che permette di condurre alcune semplici analisi su un insieme di conti bancari

– calcolo della media degli importi del saldo– calcolo del conto con il valore massimo tra i saldi

Continua…

Page 28: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

DataSetpublic class DataSet { public void add(BankAccount x) { if (x == null) return; sum = sum + x.getBalance(); if (count == 0 || maximum.getBalance() < x.getBalance()) maximum = x; count++; } public BankAccount getMaximum() { return maximum; } public double average() {return (count>0)? sum /count : Double.NaN; } private double sum; private BankAccount maximum; private int count; }

Page 29: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Esempio – Data Analysis

• Ora ripetiamo l’esempio per definire una versione della classe DataSet che permette di condurre alcune semplici analisi su un insieme di corsi universitari:

– calcolo della media del numero di studenti per corso– calcolo del corso con massimo numero di studenti

class Corso{ // . . . public double iscritti() { // ... }}

Page 30: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

DataSet – versione per Corsopublic class DataSet { public void add(Corso x) { if (x == null) return; sum = sum + x.iscritti(); if (count == 0 || maximum.iscritti() < x.iscritti()) maximum = x; count++; }

public Corso getMaximum() { return maximum; } public double average() {return (count>0)? sum/count : Double.NaN; } private double sum; private Corso maximum; private int count; }

Page 31: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Interfacce riuso di codice

• Il meccanismo di analisi dei dati è sempre lo stesso; – si basa sull’estrazione di una misura – la differenza è solo nell’implementazione del metodo che

fornisce la misura

• Possiamo uniformare: – è sufficiente stabilire una modalità uniforme per estrarre la

misura.

interface Measurable { double getMeasure(); }

Page 32: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Measurable BankAccounts

public class BankAccount implements Measurable { public double getMeasure() { return getBalance(); } // ... }

Continua…

Page 33: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Measurable Corsi

class Corso implements Measurable { public double getMeasure() { return iscritti(); } // . . . }

Page 34: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

DataSet – versione generica

public class DataSet{ public void add(Measurable x) {

if (x == null) return; sum = sum + x.getMeasure(); if (count == 0 || maximum.getMeasure() < x.getMeasure()) maximum = x; count++; } public Measurable getMaximum() { return maximum; } public double average() { return sum/count; } private double sum; private Measurable maximum; private int count; }

Page 35: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

DataSet Diagramma UML

dipende

implementa

Corso

Page 36: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Interfacce multiple

• Una classe può implementare più di una interfaccia

• In quel caso deve definire, public, tutti i metodi delle interfacce che implementa

• E’ automaticamente sottotipo di ciascuna delle interfacce che implementa

Page 37: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Measurable Shapes

class Quadrato implements Shape, Measurable

{ . . . public void draw(Graphics2D g) { ... } public double getMeasure() { ... } }

class Cerchio implements Shape, Measurable

{ . . . public void draw(Graphics2D g){ ... } public void getMeasure() { ... }}

Page 38: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Measurable Shapes

• Ora possiamo passare Quadrati e Cerchi sia all’interno della classe Gwin per essere disegnati, sia all’interno della classe DataSet per essere misurati

Page 39: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Conversioni di tipo

• Una interfaccia “rappresenta” tutte le classi che la implementano

• Più in generale: un supertipo rappresenta tutti i suoi sottotipi

Continua…

Page 40: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Conversioni di tipo

• 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 41: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Ancora Shapes

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 42: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Sottotipi 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

System.out.println(s.brand());

Continua…

Page 43: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Sottotipi 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 44: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

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 45: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Tipo statico e Dinamico

• Tipo statico e tipo dinamico di una variabile– tipo statico: quello dichiarato – tipo dinamico: il tipo del riferimento assegnato alla

variabile

• Il tipo dinamico può cambiare durante l’esecuzione, ma le regole garantiscono che

– Il tipo dinamico di una variabile è sempre un sottotipo del tipo statico della variabile

Continua…

Page 46: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Cast

• (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 47: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

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 48: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

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 49: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

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 50: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

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 51: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

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 52: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Domanda

• Come disegnare solo le Shapes che sono Cars?

Page 53: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Risposta

// disegna tutte le Cars della GWin

public void paint(){ for (Shape c:shapes)

if (c instanceof Car) c.draw(g); }

Page 54: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Polinomi

• Polinomi (http://www.dais.unive.it/~po/Labs/interfaces.html)

interface Poly { public Poly somma (Poly p);

public Poly derivata();

public int grado();

public boolean equals (Object q)

public boolean equals (Poly p);

public double coefficient(int degree);

}

Page 55: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Polinomi – equals()

• Notiamo le due versioni – entrambi sono necessarie – Dimostrano un aspetto interessante dell’interazione

tra il meccanismi di polimorfismo (dynamic dispatch) e di risoluzione dell’overloading

Page 56: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

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 57: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

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 58: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Polinomi – equals()

• Consideriamo:

• Data la dichiarazione q:Object la chiamata p.equals(q)viene associata alla firma Poly.equals(Object)

• eDinamincamente, poi, viene dispacciata al corpo del metodo ArrayPoly.equals(Object)

Poly p = new ArrayPoly(); Object q = new ListPoly(); p.equals(q);

Page 59: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Interfacce standard – Listeners

• Le librerie Java forniscono molte interfacce standard, che possono essere utilizzare nella programmazione

• Un insieme interessante di queste interfacce è legata al framework Swing, ed utilizzata per la programmazione ad eventi, tipica delle applicazioni con interfaccia grafica

Page 60: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Eventi, Sorgenti, e Listeners• Una interfaccia utente deve gestire una

moltitudine di eventi– eventi da tastiera, del mouse, click su pulsanti, …

• Opportuno poter discriminare diversi eventi– componenti specifiche devono poter essere

programmate senza preoccuparsi che di eventi specifici

• Necessario avere meccanismi per gestire eventi in modo selettivo

– Un meccanismo per dichiarare quali eventi si intendono gestire

Continua…

Page 61: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

• Listener: – Oggetto che viene notificato dell’occorrere di un

evento – I suoi metodi descrivono le azioni da eseguire in

risposta ad un evento

• Sorgente di eventi: – Oggetto che origina eventi, o li emette, – Notifica l’evento ai propri listeners

• Vari tipi di sorgenti– Componenti visuali: JButton, JTextField, ...– Timer, …

Eventi, Sorgenti, e Listeners

Continua…

Page 62: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

• Ogni sorgente genera un insieme ben definito di eventi

– determinato dal tipo della sorgente

• Eventi di basso livello– mouse-down/up/move, key-press/release,

component-resize/move, …

• Eventi “semantici”– ActionEvent: click su un JButton, doppio-

click su un JListItem, tick di un Timer– TextEvent: JTextField modificato da uno

o più mouse/key events

Eventi, Sorgenti, e Listeners

Continua…

Page 63: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

• Gestione mirata degli eventi– Una applicazione può decidere quali eventi gestire tra

quelli generati da ciascuna sorgente

• Registra su ciascuna componente solo i listeners degli eventi che intende gestire

Eventi, Sorgenti, e Listeners

Continua…

Page 64: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Eventi, Sorgenti, e Listeners

• Esempio: utilizziamo una componente JButton per realizzare un pulsante: associamo a ciascun pulsante un ActionListener

• Ricordiamo:

• Dobbiamo fornire una classe il cui metodo actionPerformed contiene le istruzioni da eseguire quando il pulsante viene premuto

public interface ActionListener { void actionPerformed(ActionEvent event); }

Continua…

Page 65: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Eventi, Sorgenti, e Listeners

• event contiene informazioni sull’evento (ad esempio l’istante in cui è avvenuto)

• Associamo il listener al pulsante, registrandolo sul pulsante:

• addActionListener(): un metodo di JButton

ActionListener listener = new ClickListener(); button.addActionListener(listener);

void addActionListener(ActionListener l);

Page 66: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

File ClickListener.java

01: import java.awt.event.ActionEvent;02: import java.awt.event.ActionListener;03: 04: /**05: Un action listener che stampa un messaggio06: */07: public class ClickListener implements ActionListener08: {09: public void actionPerformed(ActionEvent event)10: {11: System.out.println("I was clicked.");12: } 13: }

Page 67: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

File ClickApp.javaimport java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame; public class ClickApp{ public static void main(String[] args) { JFrame frame = new JFrame(); JButton button = new JButton("Click me!"); frame.add(button);

button.addActionListener(new ClickListener());frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } private static final int FRAME_WIDTH = 100; private static final int FRAME_HEIGHT = 60;}

Page 68: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

File ClickListener.java

Output:

Page 69: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Eventi del mouse

• mousePressed, mouseReleased: invocati quando un pulsante del mouse viene premuto o rilasciato

• mouseClicked: invocato quando un pulsante del mouse viene cliccato

• mouseEntered, mouseExited: il mouse è entrato o è uscito dall’area della componente

Page 70: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Eventi del mouse• Catturati da MouseListeners

Continua…

public interface MouseListener { // un metodo per ciascun mouse event su una componente

void mousePressed(MouseEvent event); void mouseReleased(MouseEvent event); void mouseClicked(MouseEvent event); void mouseEntered(MouseEvent event); void mouseExited(MouseEvent event); }

Page 71: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Eventi del mouse

• Se vogliamo che una componente reagisca ad eventi del mouse dobbiamo registrare un MouseListener sulla componente:

Continua…

public class MyMouseListener implements MouseListener { // Implementa i cinque metodi} MouseListener listener = new MyMouseListener(); component.addMouseListener(listener);

Page 72: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Mouse Events

class MousePressListener implements MouseListenere { public void mousePressed(MouseEvent event) { int x = event.getX(); int y = event.getY(); . . . }

// implementazione degli altri metodi dell’interfaccia}

• Tutti i metodi devono essere implementati; implementazione vuota se inutili

Page 73: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

ActionListener

• Descrive oggetti che svolgono il ruolo di gestori di eventi:

– rimane attesa (in ascolto) di un evento, per poi rispondere con una azione al momento in cui l’evento si manifesta

interface ActionListener{ void actionPerformed(ActionEvent event);}

Page 74: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Eventi di un timer

• Eventi notificati ad un ActionListener associato al timer

• Il gestore viene attivato ad ogni tick del timer

– actionPerformed() invocato ad ogni tick– event: contiene informazione sull’evento

public interface ActionListener{ void actionPerformed(ActionEvent event);}

Continua…

Page 75: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Eventi di un timer

• La gestione dell’evento avviene nel metodo actionPerformed()

• Gestioni diverse realizzate da classi diverse che implementano ActionListener

class TimerListener implements ActionListener{ public void actionPerformed(ActionEvent event) { // Eseguito ad ogni tick. }}

Continua…

Page 76: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Eventi di un timer

• Per associare un particolare listener al timer è necessario registrare il listener sul timer

• Ora possiamo far partire il timer

TimerListener listener = new TimerListener();Timer t = new Timer(interval, listener);

t.start(); // Esegue in un thread separato

tra due tick

Page 77: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

Esempio: countdown

• Un timer che esegue il countdown

Page 78: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

CountDownListener

public class CountDownApp{ public static void main(String[] args) { CountDownListener listener = new CountDownListener(10); // Millisecondi tra due tick final int DELAY = 1000; Timer t = new Timer(DELAY, listener); t.start();

JOptionPane.showMessageDialog(null, "Quit?"); System.exit(0); }}

Page 79: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

CountDownListener

• Inizializza un contatore al valore passato nel costruttore

• Ad ogni invocazione del metodo actionPerformed()

– controlla il valore del contatore e dà in output il messaggio corrispondente

– decrementa il contatore

Page 80: Interfacce e Polimorfismo - Università Ca' Foscari Veneziapo/Slides/04Interfaces.pdf · Polimorfismo – dynamic dispatch • Le regole di conversione di tipo garantiscono che una

CountDownListener

class CountDownListener implements ActionListener{ public CountDownListener(int initialCount) {

count = initialCount; }

public void actionPerformed(ActionEvent event) {

if (count >= 0) System.out.println(count);if (count == 0) System.out.println("Liftoff!");count--;

} private int count;}