1

Classi astratte
Definizione di classe astratta
   Una classe che contiene almeno un metodo astratto è detta classe astratta. Una classe astratta può contenere variabili di istanza e metodi non astratti. Una classe può essere dichiarata astratta anche se non ha metodi astratti.

Per dichiarare una classe astratta si utilizza la sintassi seguente: abstract class <nome classe> Un metodo astratto è un metodo per il quale non è stata fornita alcuna implementazione; per esempio: public abstract metodoAstratto(); Di conseguenza, una classe astratta ha almeno un metodo privo di implementazione, anche se ciò non è strettamente necessario.

A che cosa serve una classe astratta?
“Risalendo la gerarchia di ereditarietà, le classi diventano sempre più generiche. Ad un certo punto, la classe antenata diventa così generica da poter essere considerata una struttura portante per le altre classi , più che una classe con istanze specifiche utilizzabili.”1 Consideriamo nuovamente la gerarchia di classi.

P ersona

Im pi eg ato

S tud ente

public class Persona { private String nome; public String getNome() { return nome; } …………………………….. }
1

Tratto da C. S. Horstmann, G. Cornell, Java2 I fondamenti, sesta edizione, Mc Graw Hill, 2003

Bocchi Cinzia Ultimo aggiornamento: 30/09/2011

2

public class Studente extends Persona { private String corsoLaurea; ……………………………………….. } public class Impiegato extends Persona { private double stipendio; ……………………………………. } Supponiamo di voler definire un metodo getDescrizione che restituisca una breve descrizione della persona. In particolare si vuole ottenere:  per un impiegato, la visualizzazione dello stipendio;  per uno studente, il corso di laurea. E’ evidente che la classe Persona non ha informazioni sullo stipendio dell’impiegato e sul corso di laurea a cui lo studente è iscritto. Tali informazioni sono contenute all’interno delle rispettive sottoclassi. Ci troviamo quindi di fronte a 2 possibilità: 1. definire il metodo solo all’interno delle sottoclassi; 2. definire il metodo come astratto, cioè senza specificare il codice, nella superclasse e implementare il metodo in ciascuna sottoclasse. Nel primo caso il codice diventa public class Persona { private String nome; public String getNome() { return nome; } } public class Studente extends Persona { private String corsoLaurea; public String getDescrizione() { return “Lo studente frequenta “+corsoLaurea; } } public class Impiegato extends Persona { private double stipendio; public String getDescrizione() {
Bocchi Cinzia Ultimo aggiornamento: 30/09/2011

3
return “L’impiegato ha uno stipendio pari a “+stipendio;

} }

Nel seguito vedremo che la seconda possibilità è più flessibile della prima e quindi preferibile. Tuttavia, se scegliamo la seconda possibilità, il metodo getDescrizione della superclasse sarà astratto e, di conseguenza, dovrà essere definita come astratta anche la classe Persona. public abstract class Persona { private String nome; public String getNome() { return nome; } public abstract String getDescrizione(); } public class Studente extends Persona { private String corsoLaurea; public String getDescrizione() { return “Lo studente frequenta “+corsoLaurea; } } public class Impiegato extends Persona { private double stipendio; public String getDescrizione() { return “L’impiegato ha uno stipendio pari a “+stipendio; } } Il metodo astratto getDescrizione funge da segnaposto per i metodi implementati nelle sottoclassi: il codice del metodo può cambiare da sottoclasse a sottoclasse; la firma del metodo (nome, tipo restituito, specificatori di accesso, parametri) rimane la stessa.

Come si utilizza una classe astratta?
Le classi astratte non possono essere istanziate, cioè non è possibile creare un oggetto di una classe astratta. Per esempio, l’istruzione: Persona p= new Persona(); restituisce il seguente errore in fase di compilazione
Bocchi Cinzia Ultimo aggiornamento: 30/09/2011

4 Persona is abstract; cannot be instantiated
Tuttavia è possibile creare oggetti di sottoclassi concrete, nel seguente modo: Persona stu= new Studente(...); Persona imp= new Impiegato(...); stu e imp sono variabili di tipo Persona ma fanno riferimento a istanze di Studente e impiegato, rispettivamente. Naturalmente è sempre possibile creare direttamente un’istanza delle 2 sottoclassi: Studente stu= new Studente(...); Impiegato imp= new Impiegato(...); ma esistono notevoli vantaggi nell’utilizzare il formalismo precedente. In particolare, supponiamo di voler creare un array contenente oggetti Persona, siano essi impiegati o studenti e di voler ottenere la descrizione per tutti gli elementi dell’array. Se non definiamo il metodo getDescrizione come metodo astratto della classe Persona, il seguente codice restituisce errore in fase di compilazione. public class TestClasseAstratta { public static void main(String[] args) { Persona[] array= new Persona[2]; array[0]= new Studente(); array[1]= new Impiegato(); System.out.println(array[0].getDescrizione()); System.out.println(array[1].getDescrizione()); } } L’errore è il seguente

cannot find symbol: method getDescrizione()
ed è dovuto al fatto che la classe Persona non ha un metodo getDescrizione(). Definendo getDescrizione come metodo astratto di Persona, l’errore non si verifica.

___________________________________________________________________
Quest'opera è stata rilasciata con licenza Creative Commons Attribution-ShareAlike 3.0 Unported. Per leggere una copia della licenza visita il sito web http://creativecommons.org/licenses/by-sa/3.0/ o spedisci una lettera a Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

Bocchi Cinzia Ultimo aggiornamento: 30/09/2011