Unità didattica 8.1)
- Pagina 1
Unità didattica 8.2) - Pagina 2
Unità didattica 8.3) - Pagina 3
Unità didattica 8.4) - Pagina 4
1 - Unità didattica 8.1)
Caratteristiche avanzate del linguaggio
Obiettivi:
Il Lettore al termine di questo capitolo dovrà essere in grado di
Saper definire ed utilizzare i costruttori sfruttando l’overload
(unità 8.1).
Conoscere e saper sfruttare il rapporto tra i costruttori e il
polimorfismo (unità 8.1).
Conoscere e saper sfruttare il rapporto tra i costruttori e
l’ereditarietà (unità 8.2).
Saper definire ed utilizzare il reference super (unità 8.3)
Saper chiamare i costruttori con i reference this e super (unità
8.3).
Conoscere cosa sono le classi interne e le classi anonime (unità
8.4).
Unità didattica 8.1)
- Costruttori e polimorfismo
Nel modulo 2, abbiamo introdotto i metodi costruttori. Essi sono
stati definiti come dei metodi speciali, in quanto hanno delle
proprietà:
hanno lo stesso nome della classe cui appartengono
non hanno tipo di ritorno
sono chiamati automaticamente (e solamente) ogni volta che viene
istanziato un oggetto della classe cui appartengono, relativamente a
quell’oggetto
sono presenti in ogni classe.
Relativamente all’ultimo punto abbiamo anche definito il costruttore
di default, come il costruttore che è introdotto in una classe dal
compilatore al momento della compilazione, nel caso il programmatore
non gliene abbia fornito uno in maniera esplicita.
Abbiamo anche affermato che solitamente un costruttore è utilizzato
per inizializzare le variabili degli oggetti al momento
dell’istanza. Per esempio consideriamo la seguente classe che fa uso
dell’incapsulamento:
class Cliente
{
private String nome;
private String indirizzo;
private int numeroDiTelefono;
public void setNome(String n)
{
nome=n;
}
public void setIndirizzo(String ind)
{
indirizzo=ind;
}
public void setNumeroDiTelefono(String num)
{
NumeroDiTelefono =num;
}
public String getNome()
{
return nome;
}
public String getIndirizzo()
{
return indirizzo;
}
public int getNumeroDiTelefono()
{
return numeroDiTelefono;
}
}
Il lettore potrà facilmente intuire la difficoltà di utilizzare le
istanze di questa classe. Infatti, per creare un cliente
significativo, dopo averlo istanziato, dovremo chiamare tre metodi
per inizializzare le relative variabili:
Cliente cliente1= new Cliente();
cliente1.setNome("James Gosling");
cliente1.setIndirizzo("Palo Alto, California");
cliente1.setNumeroDiTelefono(0088993344556677);
Nella classe Cliente possiamo però inserire il seguente costruttore:
class Cliente
{
private String nome;
private String indirizzo;
private int numeroDiTelefono;
//il seguente è un costruttore
public Cliente(String n,String ind,int num)
{
nome=n;
indirizzo=ind;
numeroDiTelefono=num;
}
public void setNome(String n)
{
. . . . . . . . . . . . . .
Notare che il costruttore ha lo stesso nome della classe, e che non
è stato dichiarato il tipo di ritorno. Per chiamare questo
costruttore basta istanziare un oggetto dalla classe cliente
passando i dovuti parametri nel modo seguente: Cliente cliente1= new
Cliente("James Gosling", "Palo Alto,
California",0088993344556677);
N.B.: nell’esempio precedente, l’introduzione del costruttore
esplicito, implica la scomparsa del costruttore di default e la
conseguente impossibilità d’istanziare oggetti con la seguente
sintassi:
Cliente cliente1= new Cliente();
infatti, in questo modo, si tenterebbe di chiamare un costruttore
inesistente.
- Overload dei costruttori:
Anche essendo metodi particolari, i costruttori sono comunque
metodi. È possibile quindi, ed è fortemente consigliato, utilizzare
l’overload dei costruttori. Infatti, nell’esempio precedente, dato
che abbiamo inserito un costruttore esplicitamente, il compilatore
non ha inserito il costruttore di default. A questo punto non sarà
più possibile ovviamente, istanziare un oggetto senza passare
parametri al costruttore. In compenso possiamo aggiungere altri
costruttori alla classe, anche uno senza parametri, in maniera tale
da poter costruire oggetti in modo differente in fase di runtime.
Per esempio:
class Cliente
{
private String nome;
private String indirizzo;
private int numeroDiTelefono;
public Cliente(String n,String ind,int num)
{
nome=n;
indirizzo=ind;
numeroDiTelefono=num;
}
public Cliente(String n)
{
nome=n;
}
public Cliente(String n,String ind)
{
nome=n;
indirizzo=ind;
}
. . . . . . . . . . . . . .
public void setNome(String n)
{
. . . . . . . . . . . . . .
- Override dei costruttori:
Ricordiamo che l’override ci consente di riscrivere un metodo
ereditato da una superclasse. Ma, alle caratteristiche di un
costruttore, dobbiamo aggiungerne un’altra:
non è ereditato dalle sottoclassi
Infatti, se per esempio la classe Punto3d ereditasse della classe
Punto, il costruttore Punto(), quest’ultimo non si potrebbe
invocare, giacché la sintassi per istanziare un oggetto dalla classe
Punto3d,
Punto3d punto = new Punto3d();
chiamerà sempre un costruttore della classe Punto3d.
Possiamo concludere che non potendo ereditare costruttori, non si
può parlare di override di costruttori.
Unità didattica 8.1)
- Pagina 1
Unità didattica 8.2) - Pagina 2
Unità didattica 8.3) - Pagina 3
Unità didattica 8.4) - Pagina 4