Laboratorio di Sistemi Polimorfismo Java Prerequisiti: per la

Laboratorio di Sistemi
Polimorfismo
Java
Prerequisiti: per la comprensione dell'articolo è necessario conoscere il concetto di
Ereditarietà in Java.
Di solito se abbiamo la struttura di una classe con gli attributi e i metodi possiamo
istanziare oggetti a partire da quella classe. Esistono però classi particolari, chiamate
classi astratte, che non possono dare origine a oggetti. Si usano per creare una
gerarchia in cui tutte le classi discendenti devono possedere un certo metodo. In una
classe astratta, almeno un metodo è soltanto definito ma non implementato. Oppure,
in altre parole, se una classe possiede almeno un metodo astratto, è essa stessa
astratta. Poiché il metodo non possiede il codice, qualora ne fosse richiesta la sua
esecuzione, non saprebbe come comportarsi: per questo motivo non ci possono
essere oggetti creati a partire dalla classe astratta.
Per usare una classe astratta, occorre creare una sottoclasse (o più sottoclassi) in cui i
metodi non implementati vengono ridefiniti (overridding). Nella sottosclasse per ogni
metodo astratto della superclasse viene creato un nuovo metodo con lo stesso nome
del metodo non implementato, stessi parametri e valore di ritorno. Quando i metodi
sono stati tutti implementati, la superclasse in un certo senso non è più astratta e si
possono allora generare gli oggetti (per mezzo delle sue sottoclassi).
Esempio: consideriamo la seguente gerarchia:
Per comodità, supponiamo che il modificatore di visibilità degli attributi della
superclasse Animale sia protected (in questo modo, anche se le classi derivate
appartengono a package differenti rispetto alla superclasse, gli attributi della
superclasse si possono facilmente ereditare).
Osserviamo la struttura dei package:
polimorfismo.pdf
Pag. 1/5
Cozzetto ©
Laboratorio di Sistemi
Polimorfismo
Java
Segue codice delle classi:
/*
* Animale.java
*/
package classiAstratte;
/**
*
* @author maurizio
*/
public abstract class Animale {
protected String nome; // attributi “generali” della classe Animale
protected String tipoAnimale;
public Animale() {
}
public abstract void emettiVerso(); // metodo astratto
public abstract void stampa(); // metodo astratto
} // fine classe Animale
polimorfismo.pdf
Pag. 2/5
Cozzetto ©
Laboratorio di Sistemi
Polimorfismo
Java
/*
* Cane.java
*/
package classiConcrete;
import classiAstratte.Animale;
/**
*
* @author maurizio
*/
public class Cane extends Animale {
// la classe Cane estende la classe Animale per includere l'attributo “razza”
String razza;
public Cane() {
// la parola riservata super è un riferimento implicito alla superclasse
super.nome="Brick";
super.tipoAnimale="cane";
razza="Mastino napoletano";
}
@Override
// ridefinizione del metodo emettiVerso() della superclasse astratta Animale
public void emettiVerso() {
System.out.println("Io faccio \"Bau bau\"");
}
@Override
// ridefinizione del metodo toString() della classe superclasse Object
public String toString() {
return "Io sono un "+super.tipoAnimale+" e mi chiamo "+super.nome+" di razza
"+razza;
}
@Override
// ridefinizione del metodo stampa() della superclasse
public void stampa() {
System.out.println(toString());
}
} // fine classe Cane
polimorfismo.pdf
Pag. 3/5
Cozzetto ©
Laboratorio di Sistemi
Polimorfismo
Java
/*
* Gatto.java
*/
package classiConcrete;
import classiAstratte.Animale;
/**
*
* @author maurizio
*/
public class Gatto extends Animale {
public Gatto() {
super.tipoAnimale="gatto";
super.nome="MicioMiao";
}
@Override
// ridefinizione del metodo emettiVerso()
public void emettiVerso() {
System.out.println("Io faccio \"Miao Miao\"");
}
@Override
// ridefinizione di toString()
public String toString() {
return "Io sono un "+super.tipoAnimale+" e mi chiamo "+super.nome;
}
@Override
// ridefinizione di stampa()
public void stampa() {
System.out.println(toString());
}
} // fine classe Gatto
/*
* Main.java
*/
package main;
import classiConcrete.Cane;
import classiConcrete.Gatto;
polimorfismo.pdf
Pag. 4/5
Cozzetto ©
Laboratorio di Sistemi
Polimorfismo
Java
/**
*
* @author maurizio
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// istanzio un oggetto di tipo “Cane”
Cane c = new Cane();
// stampo l'oggetto
c.stampa();
// gli faccio emettere un suono
c.emettiVerso();
// istanzio un oggetto di tipo “Gatto”
Gatto g = new Gatto();
// stampo l'oggetto
g.stampa();
// gli faccio emettere un verso
g.emettiVerso();
}
} // fine classe Main
Questo semplice esempio ci introduce anche al concetto di polimorfismo (la parola
deriva dal greco e possiamo tradurla con: più forme). Abbiamo due tipi di
polimorfismo: il primo consiste nell'overloading di un metodo. Cioè la possibilità di
usare lo stesso metodo per compiere operazioni su oggetti differenti:
System.out.println(“Questa è una stringa”); // stampa di una stringa
System.out.println(24); // stampa di un intero
System.out.println(434.541); // stampa di un double
Cioè stesso oggetto e stesso metodo ma argomenti differenti. Questo tipo di
polimorfismo lo abbiamo usato spesso per fare l'overloading del costruttore.
L'altro tipo di polimorfismo consiste proprio nell'overridding di un metodo.
Infatti se c è un oggetto di tipo Cane e g è un oggetto di tipo Gatto, posso scrivere
c.emettiVerso() e g.emettiVerso()
cioè oggetti differenti ma stesso metodo (ogni animale emette un verso e ciascuno
emetterà il “proprio” verso).
polimorfismo.pdf
Pag. 5/5
Cozzetto ©