Eredità e Polimorfismo in Java Corso di Linguaggi di Programmazione ad Oggetti 1 A.A. 2003/04 A cura di Eloisa Vargiu 1 Corso di Linguaggi di Programmazione ad Oggetti 1 Definizione di Classe l Java è un linguaggio object-oriented per cui il costrutto fondamentale è quello di classe: public class MyClass { // definizione di dati membro: // slot e metodi } l La definizione dei dati membro (slot e metodi) va fatta dentro la definizione di classe Eloisa Vargiu 2 Corso di Linguaggi di Programmazione ad Oggetti 1 L’oggetto this l Per accedere ai dati membro di una classe agendo sull’oggetto corrente di una classe si usa la parola chiave this public class MyClass { private int var; public void myMethod(int var) { this.var = var ; } } Eloisa Vargiu 3 Corso di Linguaggi di Programmazione ad Oggetti 1 Classi e Tipi Primitivi l Oltre al costrutto di classe, in Java sono stati definiti 8 tipi primitivi suddivisi nelle seguenti categorie: l l l l Logici Numeri interi Numeri in virgola mobile Caratteri Eloisa Vargiu 4 Corso di Linguaggi di Programmazione ad Oggetti 1 Tipi Primitivi l Logici l l l boolean Numeri interi l l l l byte short int long Numeri in virgola mobile l l l float double Caratteri l char Eloisa Vargiu 5 Corso di Linguaggi di Programmazione ad Oggetti 1 Tipi Primitivi: Esempio public static void main(String args[]){ int i = 10 ; char c ; if (i > 0) { c = 'M' ; } else c = 'm' ; } Eloisa Vargiu 6 Corso di Linguaggi di Programmazione ad Oggetti 1 Tipi Primitivi e Classi Wrapper l I tipi primitivi Java non godono delle stesse proprietà delle classe: l l l l NON hanno slot e metodi associati NON hanno costruttori … Per poter gestire i tipi primitivi come oggetti, sono state definite e implementate apposite classi: le classi Wrapper (del package java.lang) Eloisa Vargiu 7 Corso di Linguaggi di Programmazione ad Oggetti 1 Classi Wrapper l Esiste una classe Wrapper per ogni tipo primitivo: l l l l l boolean → Boolean byte → Byte short → Short int → Integer long → Long l float → Float l double → Double l char → Character Eloisa Vargiu 8 Corso di Linguaggi di Programmazione ad Oggetti 1 Classi Wrapper: Esempio l class Integer l public Integer(int value) Integer i = new Integer(10) ; l public int intValue() int j = i.intValue() ; l public int compareTo(Integer anotherInteger) Integer k = new Integer(15) ; i.compareTo(k) ; Eloisa Vargiu 9 Corso di Linguaggi di Programmazione ad Oggetti 1 Classi e Interfacce l l Oltre al costrutto di classe, Java introduce il costrutto di Interfaccia Le interfacce Java (interface) contengono definizioni di costanti e metodi astratti l l Le costanti devono necessariamente essere inizializzate I metodi sono tutti astratti Eloisa Vargiu 10 Corso di Linguaggi di Programmazione ad Oggetti 1 Classi e Interfacce l l Per indicare che una classe incorpora il comportamento di una data interfaccia si usa la parola chiave implements Le classi possono implementare una o più interfacce Eloisa Vargiu 11 Corso di Linguaggi di Programmazione ad Oggetti 1 Classi e Interfacce: Esempio public interface MyInterface { int maxDim = 100 ; boolean isFull() ; } public class MyClass implements MyInterface { private int dim ; public boolean isFull() { return dim = maxDim ; } } Eloisa Vargiu 12 Corso di Linguaggi di Programmazione ad Oggetti 1 Classi e Interfacce l Un caso particolare di interfacce sono le Marker Interface l l Tali interfacce non dichiarano al proprio interno nessun metodo (sono vuote) Il loro scopo è quello di “marcare” le classi che le implementano Eloisa Vargiu 13 Corso di Linguaggi di Programmazione ad Oggetti 1 Classi e Interfacce: Esempio l public interface Cloneable l Una classe implementa l’interfaccia Cloneable per indicare che è possibile “clonare” tale oggetto, ovvero che si può sovrascrivere il metodo clone() della classe Object. Eloisa Vargiu 14 Corso di Linguaggi di Programmazione ad Oggetti 1 Convenzione sui Nomi l In Java, per omogeneità verso le classi standard e verso il codice scritto da altri, è consigliabile usare la seguente convenzione sull’iniziale dei nomi e sulle parole composte: Classi Iniziale maiuscola MyClass Interfacce Dati membro Oggetti Iniziale maiuscola Iniziale minuscola Iniziale minuscola MyInterface aSlot – aMethod() anObject Tipi primitivi Iniziale minuscola anInt Eloisa Vargiu 15 Corso di Linguaggi di Programmazione ad Oggetti 1 Nota sui Nomi delle Interfacce l l Anche se non esiste una convenzione esplicita, solitamente i nomi delle interfacce terminano con il post-fisso able Tale post-fisso sta ad indicare che l’interfaccia, di fatto, definisce una proprietà Eloisa Vargiu 16 Corso di Linguaggi di Programmazione ad Oggetti 1 Costruttori l l l Analogamente al C++, anche in Java esistono i costruttori Analogamente al C++, anche in Java i costruttori hanno lo stesso nome della classe Per creare una nuova istanza di un oggetto bisogna obbligatoriamente invocare una new: obj = new MyClass() ; Eloisa Vargiu 17 Corso di Linguaggi di Programmazione ad Oggetti 1 Costruttori: Esempio public class MyClass { public MyClass() { // costruttore senza parametri } public MyClass(Object anObject) { // costruttore con parametri } } Eloisa Vargiu 18 Corso di Linguaggi di Programmazione ad Oggetti 1 Distruttori l l l In Java non esistono distruttori E’ compito del Garbage Collector distruggere gli oggetti non più referenziati E’ possibile forzare il Garbage Collector invocando il metodo finalize( ) della classe Object Eloisa Vargiu 19 Corso di Linguaggi di Programmazione ad Oggetti 1 Catene di eredità l In Java tutte le classi derivano, in maniera diretta o indiretta, da una classe comune: Object Eloisa Vargiu 20 Corso di Linguaggi di Programmazione ad Oggetti 1 Catene di eredità: Esempio Object | |---Number | |---Double |---Integer | |---Boolean |---Character | |… Eloisa Vargiu 21 Corso di Linguaggi di Programmazione ad Oggetti 1 Eredità singola: Classi l l l In Java l’eredità è singola Ogni classe può ereditare solamente da un’altra classe Per indicare che una classe eredita da un’altra classe si usa la parola chiave extends Eloisa Vargiu 22 Corso di Linguaggi di Programmazione ad Oggetti 1 Eredità singola: Esempio public class Derived extends Base { // corpo della classe Derived } La seguente istruzione è implicita e può essere omessa: public class MyClass extends Object { // corpo della classe MyClass } Eloisa Vargiu 23 Corso di Linguaggi di Programmazione ad Oggetti 1 Eredità multipla: Interfacce l l l Per le interfacce l’eredità è multipla Un’interfaccia può ereditare il comportamento di una o più interfacce Per indicare che un’interfaccia eredita da un’altra interfaccia si usa la parola chiave extends Eloisa Vargiu 24 Corso di Linguaggi di Programmazione ad Oggetti 1 Eredità Multipla: Esempio public interface Derivable extends IBase1, IBase2 { // definizione dell’interfaccia // Derivable } Eloisa Vargiu 25 Corso di Linguaggi di Programmazione ad Oggetti 1 Nota sull’Eredità l Una classe può ereditare da una sola superclasse ma può implementare più interfacce così facendo Java sta in qualche modo rendendo possibile una forma di eredità multipla. Eloisa Vargiu 26 Corso di Linguaggi di Programmazione ad Oggetti 1 Eredità: Esempio public class Derived extends Base implements IBase1, IBase2 { // implementazione della classe } Eloisa Vargiu 27 Corso di Linguaggi di Programmazione ad Oggetti 1 Eredità l l L’eredità in Java è sempre pubblica Non è infatti possibile, come ad esempio in C++, stabilire metodi più sofisticati di eredità Eloisa Vargiu 28 Corso di Linguaggi di Programmazione ad Oggetti 1 L’oggetto super l Per accedere ai dati membro di una superclasse, si usa la parola chiave super public class Base { public Object obj ; … } public class Derived extends Base{ public Object obj ; public void myMethod(…) { super.obj = … ; } … } Eloisa Vargiu 29 Corso di Linguaggi di Programmazione ad Oggetti 1 Eredità: Costruttori l l Nella catena di eredità vengono ereditati anche i costruttori. Nel caso in cui il costruttore venga ridefinito nella classe derivata, è comunque possibile accedere al costruttore della classe madre usando il costrutto super(...) con gli eventuali parametri. Eloisa Vargiu 30 Corso di Linguaggi di Programmazione ad Oggetti 1 Eredità: Costruttori l l La prima istruzione che viene eseguita implicitamente quando viene invocato un costruttore è l’istruzione super( ), ovvero il costruttore senza parametri della classe base. Il richiamo esplicito di un costruttore della classe base con il costrutto super( ) (con o senza parametri) deve essere fatto come prima istruzione del costruttore. Eloisa Vargiu 31 Corso di Linguaggi di Programmazione ad Oggetti 1 Eredità: Esempio public class Base { public Base() { … } public Base(int var) { … } } public class Derived extends Base { public Derived() { super() ; … } } Eloisa Vargiu 32 Corso di Linguaggi di Programmazione ad Oggetti 1 Eredità: Esempio public class Base { public Base() { … } public Base(int var) { … } } public class Derived extends Base { public Derived(int var) { super(var) ; … } } Eloisa Vargiu 33 Corso di Linguaggi di Programmazione ad Oggetti 1 Modificatori di Accesso l I dati membro possono avere uno di quattro livelli di accesso: l l l l l l private protected public default Va indicato nella dichiarazione della variabile o del metodo Se non è esplicitamente indicato si intende il livello di default Eloisa Vargiu 34 Corso di Linguaggi di Programmazione ad Oggetti 1 Modificatori di Accesso: Esempio public class Base { private String privateSlot ; protected void protectedMethod() { ... } } public class Derived extends Base { public void publicMethod() { this.privateSlot ; // NO!!! this.protectedMethod() ; // YES!!! } } Eloisa Vargiu 35 Corso di Linguaggi di Programmazione ad Oggetti 1 Modificatori di Accesso: Esempio public class AClass { private String privateSlot ; public void publicMethod() { … } } public class AnotherClass { public void publicMethod() { AClass obj = new AClass() ; obj.privateSlot ; // NO!!! obj.publicMethod() ; // YES!!! } } Eloisa Vargiu 36 Corso di Linguaggi di Programmazione ad Oggetti 1 Eredità e Modificatori di Accesso l l In Java l’ereditarietà è sempre pubblica Nell’overriding dei metodi è comunque possibile modificare il modificatore di accesso l l La modifica è possibile solamente nella direzione di un aumento della visibilità. Non è invece consentito l’occultamento del dato Eloisa Vargiu 37 Corso di Linguaggi di Programmazione ad Oggetti 1 Overriding: Esempio public class Base { protected protectedMethod() {…} public publicMethod() {…} } public class Derived { public protectedMethod(){…}// YES!!! private publicMethod(){…} // NO!!! } Eloisa Vargiu 38 Corso di Linguaggi di Programmazione ad Oggetti 1 Polimorfismo parametric universal inclusion polymorphism overloading ad-hoc coercion Eloisa Vargiu 39 Corso di Linguaggi di Programmazione ad Oggetti 1 Polimorfismo Universale: per Inclusione l l l Gli oggetti possono manifestare un comportamento polimorfo risalendo la catena di eredità Per creare il metodo più generico possibile basterà passare come parametro un oggetto di classe Object Se si vuole che un metodo restituisca un oggetto il più generico possibile basterà restituire un oggetto di classe Object Eloisa Vargiu 40 Corso di Linguaggi di Programmazione ad Oggetti 1 Polimorfismo per Inclusione: Esempio public class Stack { public Object[] buffer ; public void push(Object obj) { … } public Object top() { …} … } Eloisa Vargiu 41 Corso di Linguaggi di Programmazione ad Oggetti 1 Polimorfismo Universale: per Genericità l l Nella versione 1.5.0-beta sono stati introdotti i Generics Dedicheremo un’intera lezione all’argomento (20 Maggio 2004) Eloisa Vargiu 42 Corso di Linguaggi di Programmazione ad Oggetti 1 Polimorfismo Ad-Hoc: Overloading l l l Un metodo può essere “sovraccaricato” per manifestare diversi comportamenti I metodi di cui si fa l’overlaoding devono essere distinguibili per numero e/o tipi di parametri passati in ingresso NON è possibile che due metodi differiscano solamente per il tipo restituito Eloisa Vargiu 43 Corso di Linguaggi di Programmazione ad Oggetti 1 Overloading: Esempio public class MyClass { public void myMethod() { … } public void myMethod(Obj obj) { … } public void myMethod(Obj obj, int v) { … } } Eloisa Vargiu 44 Corso di Linguaggi di Programmazione ad Oggetti 1 Polimorfismo Ad-Hoc: Overloading l l l Anche i costruttori possono essere “sovraccaricati” Per richiamare un costruttore dentro un altro costruttore si usa il costrutto this( ) con i relativi parametri Questo meccanismo può ovviare alla mancanza dei parametri di default Eloisa Vargiu 45 Corso di Linguaggi di Programmazione ad Oggetti 1 Overloading: Esempio public class MyClass { public void MyClass(int a, int b) { … } public void MyClass () { this(0,0) ; } } Eloisa Vargiu 46 Corso di Linguaggi di Programmazione ad Oggetti 1 Polimorfismo Ad-Hoc: Overloading l l In Java non è possibile fare l’overloading degli operatori Fa eccezione la ridefinizione dell’operatore + nella classe String che permette la concatenazione di stringhe di caratteri Eloisa Vargiu 47 Corso di Linguaggi di Programmazione ad Oggetti 1 Polimorfismo Ad-Hoc: Coercion l Sui tipi primitivi si ha la coercion implicita : double y ; int x ; System.out.println(x+y) ; >> 42.0 Eloisa Vargiu 48 Corso di Linguaggi di Programmazione ad Oggetti 1 Polimorfismo Ad-Hoc: Coercion l Per quanto riguarda gli oggetti si ha: l l up-casting implicito down-casting esplicito Eloisa Vargiu 49 Corso di Linguaggi di Programmazione ad Oggetti 1 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) ; Eloisa Vargiu 50 Corso di Linguaggi di Programmazione ad Oggetti 1 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) ; Eloisa Vargiu 51