Upload
hoangthuan
View
222
Download
0
Embed Size (px)
Citation preview
Polimorfismoper Genericità
in Java
Corso di Linguaggi diProgrammazione ad Oggetti 1
A.A. 2003/04
A cura diEloisa Vargiu
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Polimorfismo
ad-hoc
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Polimorfismo Ad-Hoc: Overloading
l Un metodo può essere “sovraccaricato” per manifestare diversi comportamenti
l I metodi di cui si fa l’overlaoding devonoessere distinguibili per numero e/o tipi diparametri passati in ingresso
l NON è possibile che due metodi differiscanosolamente per il tipo restituito
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Overloading: Esempio
public class MyClass {public void myMethod(){ … }
public void myMethod(Obj obj){ … }
public void myMethod(Obj obj, int v){ … }
}
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Polimorfismo Ad-Hoc: Overloading
l Anche i costruttori possono essere“sovraccaricati”
l Per richiamare un costruttore dentro un altrocostruttore si usa il costrutto this( ) con i relativi parametri
l Questo meccanismo può ovviare allamancanza dei parametri di default
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Overloading: Esempio
public class MyClass {public void MyClass(int a, int b){ … }
public void MyClass () { this(0,0) ;
}}
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Polimorfismo Ad-Hoc: Coercion
l Sui tipi primitivi si ha la coercion implicita :
double y ;int x ;System.out.println(x+y) ;
>> 42.0
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Polimorfismo Ad-Hoc: Coercion
l Per quanto riguarda gli oggetti si ha:l up-casting implicitol down-casting esplicito
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Coercion: Esempio
l Upcasting implicito:
public class MyClass {public void push(Object o) { … }[…]
}[…]Integer anInteger = new Integer(10);MyClass mc = new MyClass() ;mc.push(anInteger) ;
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Coercion: Esempio
l Downcasting esplicito:public class MyClass {public void push(Integer i) { … }[…]
}[…]Object anObject = new Object();Integer anInteger = new Integer(10);anObject = anInteger ;MyClass mc = new MyClass() ;mc.push((Integer) anObject) ;
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Polimorfismo Universale: per Inclusione
l Gli oggetti possono manifestare un comportamento polimorfo risalendo la catena di eredità
l Per creare il metodo più generico possibilebasterà passare come parametro un oggettodi classe Object
l Se si vuole che un metodo restituisca un oggetto il più generico possibile basteràrestituire un oggetto di classe Object
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Polimorfismo per Inclusione: Esempio
public class Stack {public Object[] buffer ;public void push(Object obj) { … }public Object top() { …}…
}
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Polimorfismo Universale: Parametrico
l La JDK1.5 introduce diverse estensioni al linguaggio, tra cui i “generics”
l I generics sono lo strumento fornito da Java per realizzare il polimorfismo parametrico
l Il comportamento e le funzionalità offerte daigenerics sono simili a quelle dei template in C++
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
I generics in unadiapositiva!
l Esempio di codice che fauso del polimorfismo per inclusione:
List myIntList = new LinkedList();
myIntList.add(newInteger(0));
Integer i = (Integer) myIntList.getFirst();
Vedi API 1.4.1
l Esempio di codice che fauso del polimorfismoparametrico
List myIntList = new LinkedList<Integer>();
myIntList.add(newInteger(0));
Integer i = myIntList.getFirst();
Vedi API 1.5.1-betaa d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Definizione di ClassiGeneriche
l La sintassi per la definizione di una classegenerica è la seguente:
modificare_di_accesso class NomeClasse<E> {modificare_di_accesso tipo_restituitonomeMetodo(E par1, …);…
}
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Definizione di ClassiGeneriche
l Un esempio è il seguente:
public class ArrayList<E> {void add(E x);…
}
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Definizione di CLassiGeneriche
l Quando viene istanziato un oggetto, tutte le occorrenze dei parametri formali di tipo sonosostituiti dal parametro attuale:
ArrayList<Integer> al = new ArrayList<Integer>() ;…
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Nota sulla traduzionedel codice generico
l Una dichiarazione di tipo generico è compilata una volta per tutte e posta in un singolo file di classe
l Non ci sono copie multiple del codice: nè in codice sorgente, nè in codice binario, nel sudisco o in memoria
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Nota sulla convenzionedei nomi
l La raccomandazione che viene fatta è che siusino nomi piccoli, possibilmente costituiti daun singolo carattere
l Il nome deve in qualche modo evocare ciò a cui si fa riferimento
l Ad esempio si usa la lettera E per indicare gliElementi di un contenitore
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Generics e Sottotipi
l Consideriamo il seguente codice:
List<String> ls = new ArrayList<String>();List<Object> lo = ls ;
l Una lista di String è una lista di Object?
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Generics e Sottotipi
l Se la rispota fosse affermativa, il seguentecodice sarebbe corretto:
lo.add(new Object()) ; String s = ls.get(0) ;
l Ma quest’ultima linea di codice cercherebbedi assegnare un Object ad uno String!
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Generics e Sottotipi
l Java risolve il problema alla radice……la riga di codice
List<Object> lo = ls;
l Genera un errore a tempo di compilazione!
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Generics e Sottotipi
l In generale non vale la seguentecorrispondenza:
Base
Derived
G<Base>
G<Derived>
X
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Wildcards
l Per poter agire lungo la catena di ereditarietàbisogna considerare parametri più flessibili
l Supponiamo di lavorare con collezioni dioggetti
l Da quanto detto poco fa Collection<Object>non è il supertipo di tutte le collezioni…
l …ma allora qual è il supertipo di tutte le collezioni?
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Wildcards
l Il supertipo di tutte le collezioni è:Collection<?>
l Si legge “collezione di sconosciuti” l Il simbolo ? è chiamato “tipo wildcard”
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Esempio di Wildcards
l Supponiamo di voler stampare tutti glielementi di una collezione.
l In maniera classica dovremmo scrivere:
void printCollection(Collection c) {Iterator i = c.iterator();for(k=0; k<c.size(); k++) {System.out.println(i.next()) ;
}
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Esempio di Wildcards
l Con la nuova sintassi possiamo scrivere:
void printCollection(Collection<?> c){for(Object e:c) {
System.out.println(e) ;}
l Da notare che l’uso di Object non comporta rischi in quanto ciascun oggetto della Collection è sicuramente un Object
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Wildcards Limitati
l Consideriamo la seguente catena di eredità:
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Shape
Circle Rectangle
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Wildcards Limitati
l Il cui codice è il seguente:
public abstract class Shape {public abstract void draw(Canvas c) ;
}public class Circle extends Shape {private int x,y, radius ;public void draw(Canvas c) { … }
}
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Wildcards Limitati
public class Rectangle extends Shape {private int x,y, width, height ;public void draw(Canvas c) { … }
}public class Canvas {public void draw(Shape s) {s.draw(this) ;
}}
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Wildcards Limitati
l Un oggetto Canvas è dunque in grado didisegnare un qualunque oggetto Shape
l Supponendo di avere una lista di Shapeconsideriamo il codice di un metodo per la stampa di oggetti di tipo Shape:
public void drawAll(List<Shape> shapes) {for(Shape s:shapes) { s.draw(this) ; }
}
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Wildcards Limitati
l Il metodo drawAll stamperebbe solamenteoggetti di tipo Shape e non i suoi sottotipi…
l Per poter stampare qualsiasi oggetto facenteparte della catena di eredità di Shape bisogna modificare la signature del metododrawAll nel seguente modo:
public void drawAll(List<? extends Shape> shapes) ;
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Wildcards Limitati
l List<? extends Shape> è un esempio diwildcard limitato che permette di utilizzarequalsiasi tipo di oggetto a patto che estendaShape.
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Metodi Generici
l Così come abbiamo visto per le classi, i metodi possono essere definiti generici
l La sintassi è la seguente:
modificatore_di_accesso <T>tipo_restituito nomeMetodo
(tipoPar1 par1, …, tipoGen<T> parG, …)
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Metodi Generici
l Un esempio è il seguente:
public <T> booleancontainsAll(Collection<T> c) { …}
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Esempio di Uso di MetodiGenerici
public class C {static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
for (T o : a) { c.add(o); }}
}
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Esempio di Uso di MetodiGenerici
l Tale metodo può essere usato con qualsiasitipo di collezione:
Object[] oa = new Object[100];Collection<Object> co = new ArrayList<Object>();C.fromArrayToCollection(oa, co);// T è un ObjectString[] sa = new String[100];Collection<String> cs = new ArrayList<String>();C.fromArrayToCollection(sa, cs);// T è uno StringC.fromArrayToCollection(sa, co);// T è un Object
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Metodi Generici e Wildcards
l Quando usare i metodi generici e quando i wildcards?
l Consideriamo il seguente esempio:
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism
interface Collection<E> {boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
}
interface Collection<E> {<T> boolean containsAll(Collection<T> c);
<T extends E> booleanaddAll(Collection<T> c);
}
Corso di Linguaggi di Programmazione ad Oggetti 1
Eloisa Vargiu
Metodi Generici e Wildcards
l Quando si vuole permettere ad un metodo dipoter avere una varietà di tipi di argomentiattuali si usano i wildcards
l Quando si vogliono esprimere dipendenze trai tipi di uno o più argomenti di un metodo e/oper il suo tipo restituito si usano i metodigenerici
a d -h o c
universal
parametric
inclusion
coercion
overloading
polymorphism