LIP: 11 Maggio 2007 Classi Astratte
Cos’e’ una Classe Astratta una classe astratta e’ un particolare tipo di classe permette di fornire una implementazione parziale
Cos’e’ una Classe Astratta definisce metodi astratti (non implementati) definisce metodi concreti (implementati eventualmente usando anche i metodi astratti) ammette la dichiarazione di variabili ammette costruttori
Cos’e’ una Classe Astratta Non e’ possibile creare oggetti istanza di una classe astratta Di conseguenza i costruttori possono essere chiamati solo dalle sottoclassi per inizializzare le variabili ereditate
Sottotipi L’implementazione e’ completata dai sottotipi, che: estendono la definizione dello stato aggiungendo nuove variabili definiscono i relativi costruttori implementano i metodi ereditati astratti eventualmente sovrascrivono quelli concreti
A cosa servono? per fattorizzare la parte comune a vari sottotipi per esempio, per definire implementazioni multiple di un tipo di dato astratto (analogo interfacce)
Perche’ non un’interfaccia? Una classe astratta e’ utile i sottotipi hanno delle parti comuni Quelle che possono essere implementate nel supertipo
Esempio La specifica di un tipo di dato astratto puo’ essere definita da un’ interfaccia I sottotipi definiscono diverse implementazioni del tipo di dato Esempio: stack di interi (con lievi modifiche)
public interface Stack { \\ OVERVIEW: uno Stack e’ una collezione di \\elementi (interi) organizzati per ordine di inserimento con una politica \\ LIFO. E’ modificabile \\metodi astratti public int size(); \\ EFFECTS: restituisce il numero di elementi di this public int top() throws EmptyException; \\ EFFECTS: se this e’ vuoto solleva EmptyException, altrimenti \\ritorna l’ultimo elemento inserito
public void pop() throws EmptyException; \\ MODIFIES: this \\ EFFECTS: se this non e’ vuoto rimuove l’ultimo elemento inserito, \\altrimenti solleva EmptyException public void push (int o); \\ MODIFIES: this \\ EFFECTS: inserisce o nella pila public int minimo() throws EmptyException; \\ EFFECTS: se this e’ vuoto solleva EmptyException, altrimenti \\restituisce il minimo degli elementi di this public String toString(); \\ EFFECTS: restituisce una stringa che contiene gli elementi di this \\ nell’ordine che hanno }
Supertipo: interfaccia Non contiene implementazione I sottotipi devono fornire tutta l’implementazione: ListStack ====> implementato con una lista concatenata VectorStack ====> implementato con un Vector Le differenze di implementazione restano invisibili al codice scritto per Stack
Supertipo: classe astratta E’ possibile implementare una parte nel supertipo in modo analogo per i due sottotipi? I metodi pop(), top(),push(),toString() devono essere astratti (dipendono dal modo in cui si implementa) I metodi size(), minimo() al contrario non dipendono dalla rappresentazione della pila, possono essere implementati nel supertipo
Metodi concreti size() si puo’ implementare utilizzando una variabile d’istanza ( protected) che memorizza il numero di elementi minimo() si puo’ implementare utilizzando i metodi astratti pop(), push() e top() (e usando la ricorsione per esempio)
Esercizio I Modificare l’interfaccia Stack Trasformarla in una classe astratta come descritto in precedenza Ricordarsi di usare abstract nella dichirazione della classe e dei metodi astratti
Esercizio II Definire un sottotipo di Stack, VectorStack Definisce un’implementazione completa della pila di interi tramite Vector
Esercizio III Il codice scritto per il supertipo Stack funziona correttamente per VectorStack come per qualsiasi altro sottotipo (p.e. tramite Lista) Insieme di metodi statici che manipolano Stack (da inserire in una classe Proc)
PRIMO METODO public static boolean cerca(Stack p, int x) { \\ REQUIRES: p non null \\EFFECTS: restituisce true se x occorre in this, false altrimenti }
SECONDO METODO: public static Stack somma(Stack p1,Stack p2) throws InvalidSizeException{ \\ REQUIRES: p1 e p2 non null \\EFFECTS: se p1 e p2 hanno lo stesso numero di \\elementi restituisce la pila ottenuta facendo \\la somma degli elementi in ogni posizione, \\ altrimenti solleva InvalidSizeException } InvalidSizeException eccezione controllata (non primitiva) Esempio: p1=[7,9,0] e p2=[13,6,1] ===== [20,15,1]
Testing Non si possono creare oggetti di tipo Stack Bisogna testare (anche i metodi statici) usando oggetti di tipo VectorStack