Eredità e Polimorfismo in Java Corso di Linguaggi di Programmazione ad Oggetti 1 A.A. 2003/04 A cura di
Definizione di Classe Java è un linguaggio object-oriented per cui il costrutto fondamentale è quello di classe: public class MyClass { // definizione di dati membro: // slot e metodi La definizione dei dati membro (slot e metodi) va fattadentro la definizione di classe
L oggetto this 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 ;
Classi e Tipi Primitivi Oltre al costrutto di classe, in Java sono stati definiti 8 tipi primitivi suddivisi nelle seguenti categorie: Logici Numeri interi Numeri in virgola mobile Caratteri
Tipi Primitivi Logici boolean Numeri interi byte short int long Numeri in virgola mobile float double Caratteri char
Tipi Primitivi: Esempio public static void main(string args[]){ int i = 10 ; char c ; if (i > 0) { c = 'M' ; else c = 'm' ;
Tipi Primitivi e Classi Wrapper I tipi primitivi Java non godono delle stesse proprietà delle classe: 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)
Classi Wrapper Esisteuna classewrapper per ogni tipo primitivo: boolean Boolean byte Byte short Short int Integer long Long float Float double Double char Character
Classi Wrapper: Esempio class Integer public Integer(int value) Integer i = new Integer(10) ; public int intvalue() int j = i.intvalue() ; public int compareto(integer anotherinteger) Integer k = new Integer(15) ; i.compareto(k) ;
Classi e Interfacce Oltre al costrutto di classe, Java introduce il costruttodi Interfaccia Le interfacce Java (interface) contengono definizioni di costanti e metodi astratti Le costanti devono necessariamente essere inizializzate I metodi sono tutti astratti
Classi e Interfacce Per indicare che una classeincorpora il comportamento di una data interfaccia si usa la parola chiave implements Le classi possono implementare una o più interfacce
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 ;
Classi e Interfacce Un caso particolare di interfacce sono le Marker Interface Tali interfacce non dichiarano al proprio interno nessun metodo (sono vuote) Il loro scopo è quello di marcare le classi che le implementano
Classi e Interfacce: Esempio public interface Cloneable Una classe implementa l interfaccia Cloneable per indicare che è possibile clonare tale oggetto, ovvero che si può sovrascrivere il metodo clone() della classe Object.
Convenzione sui Nomi 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 Interfacce Dati membro Oggetti Tipi primitivi Iniziale maiuscola Iniziale maiuscola Iniziale minuscola Iniziale minuscola Iniziale minuscola MyClass MyInterface aslot amethod() anobject anint
Nota sui Nomi delle Interfacce Anche se non esiste una convenzione esplicita, solitamente i nomi delle interfacce terminano con il post-fisso able Tale post-fissostaad indicare che l interfaccia, di fatto, definisce una proprietà
Costruttori Analogamente al C++, anche in Java esistono i costruttori Analogamente al C++, anche in Java i costruttori hanno lo stessonome della classe Per creare una nuova istanza di un oggetto bisogna obbligatoriamente invocare una new: obj = new MyClass() ;
Costruttori: Esempio public class MyClass { public MyClass() { // costruttore senza parametri public MyClass(Object anobject) { // costruttore con parametri
Distruttori 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
Catene di eredità In Java tutte le classi derivano, in maniera diretta o indiretta, da una classe comune: Object
Catene di eredità: Esempio Object ---Number ---Double ---Integer ---Boolean ---Character
Eredità singola: Classi In Java l eredità è singola Ogni classepuò ereditare solamenteda un altra classe Per indicare che una classe eredita da un altra classe si usa la parola chiave extends
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
Eredità multipla: Interfacce Per le interfacce l eredità è multipla Un interfaccia può ereditare ilcomportamento di una o più interfacce Per indicare che un interfaccia eredita da un altra interfaccia si usala parola chiave extends
Eredità Multipla: Esempio public interface Derivable extends IBase1, IBase2 { // definizione dell interfaccia // Derivable
Nota sull Eredità Una classe può ereditare da una sola superclasse ma può implementare più interfacce cosìfacendo Java stain qualche modo rendendo possibile una forma di eredità multipla.
Eredità: Esempio public class Derived extends Base implements IBase1, IBase2 { // implementazione della classe
Eredità L eredità in Java è sempre pubblica Non è infatti possibile, come ad esempio in C++, stabilire metodi più sofisticati di eredità
L oggetto super 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 = ;
Eredità: Costruttori Nella catena di ereditàvengono ereditati anche i costruttori. Nel casoin cui il costruttore venga ridefinito nella classederivata, è comunque possibile accedere al costruttore della classe madre usando il costruttosuper(...) con gli eventuali parametri.
Eredità: Costruttori 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.
Eredità: Esempio public class Base { public Base() { public Base(int var) { public class Derived extends Base { public Derived() { super() ;
Eredità: Esempio public class Base { public Base() { public Base(int var) { public class Derived extends Base { public Derived(int var) { super(var) ;
Modificatori di Accesso I dati membro possono avere uno di quattro livelli di accesso: private protected public default Va indicato nella dichiarazione della variabile o del metodo Se non è esplicitamente indicato si intende il livello di default
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!!!
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!!!
Eredità e Modificatori di Accesso In Java l ereditarietà è sempre pubblica Nell overriding dei metodi è comunque possibile modificare il modificatore di accesso La modifica è possibile solamente nella direzione di un aumento della visibilità. Non è invece consentito l occultamento del dato
Overriding: Esempio public class Base { protected protectedmethod() { public publicmethod() { public class Derived { public protectedmethod(){ // YES!!! private publicmethod(){ // NO!!!
Polimorfismo parametric universal inclusion polymorphism overloading ad-hoc coercion
Polimorfismo Universale: per Inclusione 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 classeobject Se si vuole che un metodo restituisca un oggettoil più generico possibile basterà restituire un oggetto di classe Object
Polimorfismo per Inclusione: Esempio public class Stack { public Object[] buffer ; public void push(object obj) { public Object top() {
Polimorfismo Universale: per Genericità Nella versione 1.5.0-beta sono stati introdotti i Generics Dedicheremo un intera lezione all argomento (20 Maggio 2004)
Polimorfismo Ad-Hoc: Overloading 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
Overloading: Esempio public class MyClass { public void mymethod() { public void mymethod(obj obj) { public void mymethod(obj obj, int v) {
Polimorfismo Ad-Hoc: Overloading Anche i costruttori possono essere sovraccaricati Per richiamare un costruttore dentro un altro costruttore si usa il costrutto this( ) con i relativi parametri Questomeccanismo può ovviare alla mancanza dei parametri di default
Overloading: Esempio public class MyClass { public void MyClass(int a, int b) { public void MyClass () { this(0,0) ;
Polimorfismo Ad-Hoc: Overloading In Java non è possibile fare l overloading degli operatori Faeccezione la ridefinizione dell operatore + nella classe String che permette la concatenazione di stringhe di caratteri
Polimorfismo Ad-Hoc: Coercion Sui tipi primitivi si ha la coercion implicita : double y ; int x ; System.out.println(x+y) ; >> 42.0
Polimorfismo Ad-Hoc: Coercion Per quanto riguarda gli oggetti si ha: up-casting implicito down-casting esplicito
Coercion: Esempio Upcasting implicito: public class MyClass { public void push(object o) { [ ] [ ] Integer aninteger = new Integer(10); MyClass mc = new MyClass() ; mc.push(aninteger) ;
Coercion: Esempio 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) ;