Le gerarchie di tipi 1 Supertipi e sottotipi

  • Slides: 55
Download presentation
Le gerarchie di tipi 1

Le gerarchie di tipi 1

Supertipi e sottotipi 4 un supertipo – class – interface 4 può avere più

Supertipi e sottotipi 4 un supertipo – class – interface 4 può avere più sottotipi – un sottotipo extends il supertipo (class) • un solo supertipo (ereditarietà singola) – un sottotipo implements il supertipo (interface) • più supertipi interface 4 la gerarchia può avere un numero arbitrario di livelli 2

Come si può utilizzare una gerarchia di tipi 4 implementazioni multiple di un tipo

Come si può utilizzare una gerarchia di tipi 4 implementazioni multiple di un tipo – i sottotipi non aggiungono alcun comportamento nuovo – la classe che implementa il sottotipo implementa esattamente il comportamento definito dal supertipo 4 il sottotipo estende il comportamento del suo supertipo fornendo nuovi metodi o nuove caratteristiche 4 Questa forma di astrazione essenziale per lo sviluppo incrementale del codice e per il riutilizzo del codice 4 dal punto di vista semantico, supertipo e sottotipo sono legati dal principio di sostituzione 3

Principio di sostituzione 4 un oggetto del sottotipo può essere sostituito ad un oggetto

Principio di sostituzione 4 un oggetto del sottotipo può essere sostituito ad un oggetto del supertipo senza influire sul comportamento dei programmi che lo utilizzano 4 i sottotipi supportano il comportamento del supertipo – per esempio, un programma scritto in termini del tipo Persona deve lavorare correttamente su oggetti del sottotipo Studente 4 per questo, il sottotipo deve soddisfare le specifiche del supertipo (cosa vuol dire? ) 4

Sommario 4 Specifica del supertipo e del sottotipo 4 Implementazione 4 Relazione tra le

Sommario 4 Specifica del supertipo e del sottotipo 4 Implementazione 4 Relazione tra le specifiche del sottotipo e supertipo (principio di sostituzione) 5

Definizione di una gerarchia di tipi: specifica 4 specifica del tipo superiore della gerarchia

Definizione di una gerarchia di tipi: specifica 4 specifica del tipo superiore della gerarchia – come quelle che già conosciamo – l’unica differenza è che può essere parziale • per esempio, possono mancare i costruttori 4 Puo’ essere una interfaccia o una classe astratta 6

Definizione di una gerarchia di tipi: specifica 4 specifica di un sottotipo – la

Definizione di una gerarchia di tipi: specifica 4 specifica di un sottotipo – la specifica di un sottotipo è data relativamente a quella dei suoi supertipi – non si ridanno quelle parti delle specifiche del supertipo che non cambiano – vanno specificati • i costruttori del sottotipo • i metodi “nuovi” forniti dal sottotipo • i metodi del supertipo che il sottotipo ridefinisce – come vedremo sono ammesse modifiche (anche se molto limitate)Sß nelle loro pre-post condizioni 7

Definizione di una gerarchia di tipi: implementazione 4 implementazione del supertipo – puo’ essere

Definizione di una gerarchia di tipi: implementazione 4 implementazione del supertipo – puo’ essere implementato completamente (classe) – può non essere implementato affatto (interfaccia) – può avere implementazioni parziali (classe astratta) • alcuni metodi sono implementati, altri no • Una caratteristica fondamentale della implementazione: se permette a potenziali sottotipi l’ accesso a variabili o metodi di istanza che un “normale” utente del supertipo non può vedere (vedi l’uso del modificatore protected) • 8

Definizione di una gerarchia di tipi: implementazione 4 i sottotipi sono implementati come estensioni

Definizione di una gerarchia di tipi: implementazione 4 i sottotipi sono implementati come estensioni dell’implementazione del supertipo, come prima – la rep degli oggetti del sottotipo contiene anche le variabili di istanza definite nell’implementazione del supertipo (quelle ereditate) – alcuni metodi possono essere ereditati – di altri il sottotipo può definire una nuova implementazione (overridding) 9

Interfacce e Classi 4 i supertipi sono definiti da – classi – interfacce 4

Interfacce e Classi 4 i supertipi sono definiti da – classi – interfacce 4 le classi possono essere – astratte • forniscono un’implementazione parziale del tipo – non hanno oggetti – il codice esterno non può chiamare i loro costruttori – possono avere metodi astratti la cui implementazione è lasciata a qualche sottoclasse – concrete • forniscono un’implementazione piena del tipo 4 le classi astratte e concrete possono contenere metodi finali – non possono essere reimplementati da sottoclassi 10

Gerarchie di tipi in Java: supertipi 2 4 le interfacce definiscono solo il tipo

Gerarchie di tipi in Java: supertipi 2 4 le interfacce definiscono solo il tipo (specifica) e non implementano nulla – contengono solo (le specifiche di) metodi • pubblici • non statici • astratti –il codice esterno non può creare oggetti (non ci sono costruttori) 11

Gerarchie di tipi in Java: sottotipi 1 4 una sottoclasse dichiara la superclasse che

Gerarchie di tipi in Java: sottotipi 1 4 una sottoclasse dichiara la superclasse che estende (e/o le interfacce che implementa) – ha tutti i metodi della superclasse con gli stessi nomi e segnature – può implementare i metodi astratti e reimplementare i metodi normali (purché non final) – qualunque metodo sovrascritto deve avere segnatura identica a quella della superclasse • ma i metodi della sottoclasse possono sollevare meno eccezioni 4 la rappresentazione di un oggetto di una sottoclasse consiste delle variabili di istanza proprie e di quelle dichiarate per la superclasse – quelle della superclasse non possono essere accedute direttamente se sono (come dovrebbero essere) dichiarate private 4 ogni classe che non estenda esplicitamente un’altra classe estende implicitamente Object 12

Modificatore protected 4 la superclasse può lasciare parti della sua implementazione accessibili alle sottoclassi

Modificatore protected 4 la superclasse può lasciare parti della sua implementazione accessibili alle sottoclassi – dichiarando metodi e variabili protected • implementazioni delle sottoclassi piú efficienti • si perde l’astrazione completa, che dovrebbe consentire di reimplementare la superclasse senza influenzare l’implementazione delle sottoclassi 4 meglio lasciare la rappresentazione della superclasse private ed interagirvi solo attraverso le loro interfacce pubbliche (tramite i metodi pubblici) 13

Un esempio di gerarchia con supertipo classe concreta 4 in cima alla gerarchia c’è

Un esempio di gerarchia con supertipo classe concreta 4 in cima alla gerarchia c’è una variante di Int. Set – la solita, con in più il metodo subset – la classe non è astratta – fornisce un insieme di metodi che le sottoclassi possono ereditare, estendere o sovrascrivere 14

Specifica del supertipo public class Int. Set { // OVERVIEW: un Int. Set è

Specifica del supertipo public class Int. Set { // OVERVIEW: un Int. Set è un insieme modificabile di interi di // dimensione qualunque public Int. Set () // EFFECTS: inizializza this a vuoto public void insert (int x) // MODIFIES: this // EFFECTS: aggiunge x a this public void remove (int x) // MODIFIES: this // EFFECTS: toglie x da this public boolean is. In (int x) // EFFECTS: se x appartiene a this ritorna true, altrimenti false public int size () // EFFECTS: ritorna la cardinalità di this public Iterator elements () // EFFECTS: ritorna un generatore che produrrà tutti gli elementi di // this (come Integers) ciascuno una sola volta, in ordine arbitrario // REQUIRES: this non deve essere modificato finché il generatore è in // uso public boolean subset (Intset s) } // EFFECTS: se s è un sottoinsieme di this ritorna true, altrimenti // false 15

Implementazione del supertipo public class Int. Set { // OVERVIEW: un Int. Set è

Implementazione del supertipo public class Int. Set { // OVERVIEW: un Int. Set è un insieme modificabile di interi di // dimensione qualunque private Vector els; // la rappresentazione public Int. Set () {els = new Vector(); } // EFFECTS: inizializza this a vuoto private int get. Index (Integer x) {. . . } // EFFECTS: se x occorre in this ritorna la posizione in cui si // trova, altrimenti -1 public boolean is. In (int x) // EFFECTS: se x appartiene a this ritorna true, altrimenti false {return get. Index(new Integer(x)) >= 0; } public boolean subset (Intset s) // EFFECTS: se s è un sottoinsieme di this ritorna true, altrimenti // false } {if (s == null) return false; for (int i = 0; i < els. size(); i++) if (!s. is. In(((Integer) els. get(i)). int. Value())) return false; return true; } 16

Nota 4 La rappresentazione (Vettore els) e’ privata 4 I sottotipi la ereditano ma

Nota 4 La rappresentazione (Vettore els) e’ privata 4 I sottotipi la ereditano ma non possono direttamente accedere 4 Non e’ un problema perche’ c’e’ un metodo iteratore 4 La scelta di rendere visibile o meno la rappresentazione ai sottotipi (che verranno eventualmente progettati in seguito per estendere il tipo) dipende dai metodi pubblici forniti 17

Un sottotipo: Max. Int. Set 4 si comporta come Int. Set – ma ha

Un sottotipo: Max. Int. Set 4 si comporta come Int. Set – ma ha un metodo nuovo max • che ritorna l’elemento massimo nell’insieme – la specifica di Max. Int. Set definisce solo quello che c’è di nuovo • il costruttore • il metodo max – tutto il resto della specifica viene ereditato da Int. Set 18

Specifica del sottotipo public class Max. Int. Set extends Int. Set { // OVERVIEW:

Specifica del sottotipo public class Max. Int. Set extends Int. Set { // OVERVIEW: un Max. Int. Set è un sottotipo di Int. Set che lo estende con // il metodo max public Max. Int. Set () // EFFECTS: inizializza this al Max. Int. Set vuoto public int max () throws Empty. Exception // EFFECTS: se this è vuoto solleva Empty. Exception, altrimenti // ritorna l’elemento massimo in this } 19

Implementazione di Max. Int. Set 4 La rappresentazione di Max. Int. Set e’ private

Implementazione di Max. Int. Set 4 La rappresentazione di Max. Int. Set e’ private 4 Non e’ possibile accedere dalla sottoclasse al vettore els 4 L’unico modo per calcolare il massimo e’ tramite il generatore 20

public class Max. Int. Set { public Max. Int. Set () // EFFECTS: inizializza

public class Max. Int. Set { public Max. Int. Set () // EFFECTS: inizializza this al Max. Int. Set vuoto { super( ); } public int max () throws Empty. Exception { if (size()==0) throw new Empty. Exception(“max”); Iterator g=elements(); int max= ((Integer) g. next()). int. Value(); while (g. has. Next()) { int el=((Integer) g. next()). int. Value(); if (el > max) {max=el; } } return max; } } 21

Implementazione di Max. Int. Set 4 per evitare di generare ogni volta tutti gli

Implementazione di Max. Int. Set 4 per evitare di generare ogni volta tutti gli elementi dell’insieme, memorizziamo in una variabile di istanza di Max. Int. Set il valore massimo corrente – oltre ad implementare max – dobbiamo pero’ rimplementare i metodi modificatori (insert e remove ) per tenere aggiornato il valore massimo corrente – sono i soli metodi per cui c’è overriding – tutti gli altri vengono ereditati da Int. Set 22

Implementazione del sottotipo 1 public class Max. Int. Set { // OVERVIEW: un Max.

Implementazione del sottotipo 1 public class Max. Int. Set { // OVERVIEW: un Max. Int. Set è un sottotipo di Int. Set che lo estende con // il metodo max private int mass; // l’elemento massimo, se this non è vuoto public Max. Int. Set () // EFFECTS: inizializza this al Max. Int. Set vuoto { super( ); }. . . } 4 chiamata esplicita del costruttore del supertipo – potrebbe in questo caso essere omessa – necessaria se il costruttore ha parametri 4 nient’altro da fare – perché mass non ha valore quando els è vuoto 23

Implementazione del sottotipo 2 public class Max. Int. Set extends Int. Set { private

Implementazione del sottotipo 2 public class Max. Int. Set extends Int. Set { private int mass; ……. public int max () throws Empty. Exception // EFFECTS: se this è vuoto solleva Empty. Exception, altrimenti // ritorna l’elemento massimo in this {if (size( ) == 0) throw new Empty. Exception(“Max. Int. Set. max”); return mass; }. . . } 4 usa un metodo ereditato dal supertipo (size) 24

Implementazione del sottotipo 3 public class Max. Int. Set extends Int. Set { private

Implementazione del sottotipo 3 public class Max. Int. Set extends Int. Set { private int mass; . . . public void insert (int x) { if (size() == 0 || x > mass) mass = x; super. insert(x); }. . . } 4 ha bisogno di usare il metodo insert del supertipo, anche se overriden – attraverso il prefisso super • analogo a this – non trattato nella nostra semantica operazionale 25

Implementazione del sottotipo 4 public class Max. Int. Set extends Int. Set { private

Implementazione del sottotipo 4 public class Max. Int. Set extends Int. Set { private int mass; . . . public void remove (int x) { super. remove(x); if (size() == 0 || x < mass) return; Iterator g = elements(); mass = ((Integer) g. next()). int. Value(); while (g. has. Next() { int z = ((Integer) g. next( )). int. Value(); if (z > mass) mass = z; } return; } } 4 anche qui si usa il metodo overriden del supertipo – oltre ai metodi ereditati size e elements 26

Procedura stand-alone? 4 perché non realizzare semplicemente un metodo max stand alone esterno alla

Procedura stand-alone? 4 perché non realizzare semplicemente un metodo max stand alone esterno alla classe Int. Set? – facendo un sottotipo si implementa max in modo più efficiente (si aggiorna solo quando necessario a seguito di modifiche insert o remove) – Se dovessi realizzare la procedura fuori dalla classe dovremmo per forza generare, tramite l’iteratore, tutti gli elementi e confrontarli fino a trovare il max – Analogamente alla prima implementazione vista (meno efficiente) 27

Funzione di astrazione di sottoclassi di una classe concreta 4 definita in termini di

Funzione di astrazione di sottoclassi di una classe concreta 4 definita in termini di quella del supertipo – nome della classe come indice per distinguerle 4 funzione di astrazione per Max. Int. Set a. Max. Int. Set(c) = a. Int. Set(c) 4 la funzione di astrazione è la stessa di Int. Set perché produce lo stesso insieme di elementi dalla stessa rappresentazione (els) – il valore della variabile mass non ha influenza sull’insieme rappresentato 28

Invariante di rappresentazione di sottoclassi di una classe concreta 4 invariante di rappresentazione per

Invariante di rappresentazione di sottoclassi di una classe concreta 4 invariante di rappresentazione per Max. Int. Set IMax. Int. Set (c) = c. size() > 0 ==> (c. mass appartiene a a. Int. Set(c) && per tutti gli x in a. Int. Set(c), x <= c. mass) 4 usa la funzione di astrazione del supertipo per riferirsi all’insieme 4 Specifica il legame tra mass e l’insieme 29

Notate che 4 l’invariante della sottoclasse non include (e non utilizza in questo caso)

Notate che 4 l’invariante della sottoclasse non include (e non utilizza in questo caso) l’invariante della superclasse 4 tocca all’implementazione di Int. Set preservare la sua invariante che e’ indipendente dalla sottoclasse 4 Infatti, le operazioni di Max. Int. Set non possono interferire con l’invariante del supertipo perché operano sulla rep del supertipo solo attraverso i suoi metodi pubblici 4 ma la correttezza dell’implementazione di Int. Set è chiaramente necessaria per la correttezza della sottoclasse 30

Cosa succede se il supertipo fa vedere la rappresentazione? 4 l’efficienza di remove potrebbe

Cosa succede se il supertipo fa vedere la rappresentazione? 4 l’efficienza di remove potrebbe essere migliorata – questa versione richiede di visitare els due volte • per rimuovere l’elemento (attraverso la remove della superclasse) • per aggiornare il nuovo mass (utilizzando l’iteratore) 4 dichiarando els protected nell’implementazione di Int. Set 4 Basterebbe visitare una sola volta il vettore 31

Svantaggi 4 Max. Int. Set in questo caso, l’invariante di rappresentazione di deve includere

Svantaggi 4 Max. Int. Set in questo caso, l’invariante di rappresentazione di deve includere quello di Int. Set – perché l’implementazione di Max. Int. Set potrebbe violarlo IMax. Int. Set (c) = IInt. Set (c) && c. size() > 0 ==> (c. mass appartiene a a. Int. Set(c) && per tutti gli x in a. Int. Set(c), x <= c. mass) • Bisogna fare vedere che i metodi della sottoclassi 32 preservano l’invariante della superclasse

Inoltre 4 Si perde l’astrazione verso la sottoclasse 4 Se cambiamo la rappresentazione della

Inoltre 4 Si perde l’astrazione verso la sottoclasse 4 Se cambiamo la rappresentazione della superclasse dobbiamo reimplementare anche la sottoclasse che accede alla rappresentazione 4 Spesso la soluzione piu’ efficiente non e’ quella metodologicamente migliore 33

Classi astratte come supertipi 4 implementazione parziale di un tipo 4 può avere variabili

Classi astratte come supertipi 4 implementazione parziale di un tipo 4 può avere variabili di istanza e uno o piú costruttori 4 non ha oggetti 4 i costruttori possono essere chiamati solo dalle sottoclassi per inizializzare la parte di rappresentazione della superclasse 4 contiene metodi astratti (senza implementazione) e metodi concreti (implementati) 34

Classi astratte come supertipi 4 può contenere metodi regolari (implementati) – questo evita di

Classi astratte come supertipi 4 può contenere metodi regolari (implementati) – questo evita di implementare piú volte i metodi quando la classe abbia piú sottoclassi e permette di dimostrare più facilmente la correttezza – l’implementazione può utilizzare i metodi astratti – i metodi implementati, i costruttori e le variabili d’istanza della superclasse catturano la parte generica dell’implementazione, comune ai sottotipi – i sottotipi forniscono i dettagli specifici (aggiuntivi) e l’implementazione delle parti mancanti 35

Interfaccia 4 Nelle classi astratte c’e’ una implementazione parziale, astrae la parte comune ai

Interfaccia 4 Nelle classi astratte c’e’ una implementazione parziale, astrae la parte comune ai sottotipi 4 Nelle interfacce non c’e’ alcuna implementazione (in pratica tutti i metodi sono astratti) 36

Perché può convenire trasformare Int. Set in una classe astratta 4 vogliamo definire (come

Perché può convenire trasformare Int. Set in una classe astratta 4 vogliamo definire (come sottotipo di Int. Set) il tipo Sorted. Int. Set – il generatore elements fornisce accesso agli elementi in modo ordinato – un nuovo metodo subset (overloaded) per ottenere una implementazione più efficiente quando l’argomento è di tipo Sorted. Int. Set (se sono sorted non ho bisogno di confrontare ogni elemento del primo insieme con ogni elemento del secondo!) 4 vediamo cosa vorremmo per la specifica di Sorted. Int. Set 37

Specifica del sottotipo public class Sorted. Int. Set extends Int. Set { // OVERVIEW:

Specifica del sottotipo public class Sorted. Int. Set extends Int. Set { // OVERVIEW: un Sorted. Int. Set è un sottotipo di Int. Set che lo estende // con i metodi max e subset(Sorted. Int. Set) e in cui gli elementi sono // accessibili in modo ordinato public Sorted. Int. Set () // EFFECTS: inizializza this al Sorted. Int. Set vuoto public int max () throws Empty. Exception // EFFECTS: se this è vuoto solleva Empty. Exception, altrimenti // ritorna l’elemento massimo in this 38

Specifica del sottotipo public Iterator elements () // EFFECTS: ritorna un generatore che produrrà

Specifica del sottotipo public Iterator elements () // EFFECTS: ritorna un generatore che produrrà tutti gli elementi di // this (come Integers) ciascuno una sola volta, in ordine crescente // REQUIRES: this non deve essere modificato finché il generatore è in public boolean subset (Sorted. Intset s) // EFFECTS: se s è un sottoinsieme di this ritorna true, altrimenti // false } 4 L’iteratore è overridden (la postcondizione è diversa da quella della superclasse) 4 mentre subset è overloaded (la specifica è uguale, il tipo e’ diverso) 4 In Sorted. Int. Set ho due diversi metodi subset 39

Implementazione del sottotipo 4 la rappresentazione degli oggetti di tipo Sorted. Int. Set potrebbe

Implementazione del sottotipo 4 la rappresentazione degli oggetti di tipo Sorted. Int. Set potrebbe utilizzare una lista ordinata – Avremmo due variabili d’istanza, la variabile di istanza ereditata da Int. Set (utilizzata dai metodi eredidati quali insert e remove) – Bisogna mantenere la consistenza tra le due rappresentazioni (poco efficiente e complicato) – Se anche ridefinissi tutti i metodi per la lista ordinata la variabile d’istanza eredidata non servirebbe a nulla (poco senso) 40

Soluzione migliore – Eliminare il vettore els da Int. Set – senza els, Int.

Soluzione migliore – Eliminare il vettore els da Int. Set – senza els, Int. Set non può avere oggetti e quindi deve essere ASTRATTA – Realizzare i due casi Ordinato e non Ordinato come sottotipi della classe astratta – Per progettare la classe astratta bisogna capire se c’e’ qualche informazione che puo’ essere data in modo comune alle due sottoclassi, var. d’istanza o metodi? – Altrimenti e’ conveniente usare una interfaccia 41

Int. Set come classe astratta 4 specifica uguale a quella gia’ vista (solo che

Int. Set come classe astratta 4 specifica uguale a quella gia’ vista (solo che alcuni metodi sono astratti) 4 dato che la parte importante della rappresentazione (come sono memorizzati gli elementi dell’insieme) non è definita qui, devono essere astratti i metodi insert, remove, elements e rep. Ok 4 is. In, subset possono essere implementati in termini del metodo astratto elements 42

Int. Set implementazione 4 size potrebbe essere implementata in termini di elements – inefficiente

Int. Set implementazione 4 size potrebbe essere implementata in termini di elements – inefficiente 4 teniamo traccia nella superclasse della dimensione con una variabile intera sz – che è ragionevole sia visibile dalle sottoclassi (protected) – la superclasse non può nemmeno garantire proprietà di sz 4 non c’è funzione di rappresentazione – tipico delle classi astratte, perché la vera implementazione è fatta nelle sottoclassi 43

Implementazione di Int. Set come classe astratta public abstract class Int. Set { protected

Implementazione di Int. Set come classe astratta public abstract class Int. Set { protected int sz; // la dimensione // costruttore public Int. Set () {sz = 0 ; } // metodi astratti public abstract void insert (int x); public abstract void remove (int x); public abstract Iterator elements ( ); public boolean subset (Intset s); public abstract boolean rep. Ok ( ); // metodi concreti public boolean is. In (int x) {Iterator g = elements (); Integer z = new Integer(x); while (g. has. Next()) if (g. next(). equals(z)) return true; return false; } public int size () {return sz; } // implementazione di subset} 44

Specifica della sottoclasse Sorted. Int. Set 1 4 E’ una classe concreta (completamente implementata)

Specifica della sottoclasse Sorted. Int. Set 1 4 E’ una classe concreta (completamente implementata) come quella che abbiamo visto solo che ora Int. Set e’ astratta 4 si aggiungono il costruttore, il metodo max 4 inoltre l’iteratore elements e’ overriden (cambia la postcondizione) 4 si aggiunge un metodo subset overloaded 45

Implementazione della sottoclasse Sorted. Int. Set 1 4 Rappresentazione dell’insieme ordinato come Ordered. Int.

Implementazione della sottoclasse Sorted. Int. Set 1 4 Rappresentazione dell’insieme ordinato come Ordered. Int. List su cui si assumono anche delle operazioni size e max 4 Si implementano tutti – Metodi astratti (della superclasse) – Costruttore – Metodi overloaded o overriden (tipo subset) 4 I metodi non astratti (tipo size o is. In) che sono definiti in base ai metodi astratti vengono eredidati 46

Implementazione della sottoclasse Sorted. Int. Set 1 public class Sorted. Int. Set extends Int.

Implementazione della sottoclasse Sorted. Int. Set 1 public class Sorted. Int. Set extends Int. Set { private Ordered. Int. List els; // la rappresentazione // costruttore public Sorted. Int. Set () {els = new Ordered. Int. List() ; } // metodi public int max () throws Empty. Exception { if (sz == 0) throw new Empty. Exception("Sorted. Int. Set. max"); return els. max( ); } public Iterator elements ( ) {return els. elements(); } // implementations of insert, remove . . . } 4 Si usa l’iteratore delle liste ordinate 4 insert e remove si implementano banalmente usando le operazioni relative sulle liste ordinate (non li facciamo vedere) 47

Implementazione della sottoclasse Sorted. Int. Set 2 public class Sorted. Int. Set extends Int.

Implementazione della sottoclasse Sorted. Int. Set 2 public class Sorted. Int. Set extends Int. Set { private Ordered. Int. List els; // la rappresentazione. . . public boolean subset (Int. Set s) {. . . } public boolean subset (Sorted. Int. Set s) // qui si approfitta del fatto che small. To. Big di Ordered. Int. List // ritorna gli elementi in ordine crescente } 4 Due metodi subset (uno overloaded, l’altro eredidato) 4 La scelta del metodo dipende dal tipo del parametro (se Int. Set quello della super, se Sorted. Int. Set quello della sotto) 4 Differiscono solo in efficienza 4 Lo fate per esercizio 48

Per esercizio GInt. Set 4 Altro sottotipo della classe astratta (insieme non ordinato) 4

Per esercizio GInt. Set 4 Altro sottotipo della classe astratta (insieme non ordinato) 4 E’ una classe concreta (completamente implementata) come quella che abbiamo visto solo che ora Int. Set e’ astratta 4 Va definito il costruttore, i metodi di inserimento, rimozione e l’iteratore 49

Vantaggio della gerarchia 4 Alcune operazioni sono definite in modo comune tra i diversi

Vantaggio della gerarchia 4 Alcune operazioni sono definite in modo comune tra i diversi sottotipi (quelli implementati nella classe astratta 4 Le due sottoclassi concrete definiscono implementazioni diverse, ordinato non ordinato 4 Il codice scritto per il supertipo funziona per i due sottotipi 50

Gerarchie di classi astratte 4 anche le sottoclassi possono essere astratte 4 possono continuare

Gerarchie di classi astratte 4 anche le sottoclassi possono essere astratte 4 possono continuare ad elencare come astratti alcuni dei metodi astratti della superclasse 4 possono introdurre nuovi metodi astratti 51

Interfacce 4 contiene solo metodi non statici, pubblici (non è necessario specificarlo) 4 tutti

Interfacce 4 contiene solo metodi non statici, pubblici (non è necessario specificarlo) 4 tutti i metodi sono astratti 4 è implementata da una classe che abbia la clausola implements nell’intestazione 4 un esempio che conosciamo: Iterator public interface Iterator { public boolean has. Next ( ); // EFFECTS: restituisce true se ci sono altri elementi // altrimenti false public Object next throws No. Such. Element. Exception; // MODIFIES: this // EFFECTS: se ci sono altri elementi da generare dà il // successivo e modifica lo stato di this, altrimenti // solleva No. Such. Element. Exception (unchecked)} 52

Ereditarietà multipla 4 una classe può estendere soltanto una classe 4 ma può implementare

Ereditarietà multipla 4 una classe può estendere soltanto una classe 4 ma può implementare una o piú interfacce 4 si riesce così a realizzare una forma di ereditarietà multipla – nel senso di supertipi multipli – anche se non c’è niente di implementato che si eredita dalle interfacce public class Sorted. Int. Set extends Int. Set implements Sorted. Collection {. . } 4 Sorted. Int. Set è sottotipo sia di Int. Set che di Sorted. Collection 53

A cosa servono le interfacce? 4 A realizzare implementazioni multiple di un tipo di

A cosa servono le interfacce? 4 A realizzare implementazioni multiple di un tipo di dato astratto 4 Per esempio potremmo definire Int. Set come interfaccia 4 Definire sottotipi di Int. Set che la implementano in modo diverso (con un vettore, o con una lista) 4 In questo modo l’interfaccia maschera l’implementazione (astrae dall’implemenazione) 54

A cosa servono le interfacce? 4 A realizzare tipi con un insieme di operazioni

A cosa servono le interfacce? 4 A realizzare tipi con un insieme di operazioni in comune (come nel caso di Iterator o Comparable) 4 Il codice scritto guardando l’interfaccia astrae dal particolare generatore 55