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