PDA

View Full Version : [JAVA] Implementazioni multiple


D4rkAng3l
17-05-2009, 18:52
Ragazzi,
stò un po' impicciato perchè il libro di testo del corso di metodologie di programmazione se per la parte teorica è molto chiaro...appena si addentra in esempi pratici mi pare un po' delirante anche perchè inizia gli esempi ma li lascia sempre parzialmente implementati (poi ditemi voi...magari sono stupido io)

Praticamente per spiegare la possibilità in Java di realizzare implementazioni multiple fà questo esempio:

Ho una classe abstract IntList che rappresenta l'astrazione di una lista di interi, tale classe non ha alcuna rappresentazione (non ha variabili di istanza), ha alcuni metodi definiti come abstract ed altri metodi implementati che vanno bene per tutte le varie possibili estensioni e che veranno ereditati dalle estensioni (è giusta sta cosa?)

Poi estendo tale classe abstract mediante 2 classi concrete:
EmptyIntList che rappresenta la lista vuota e FullIntList che rappresenta una lista che contiene qualcosa (e già per questo motivo mi sembra un esempio stupido...non ha molto senso secondo me rappresentare un tipo di dato lista vuota con tutti metodi più o meno inutili)

Il codice delle 3 classi è il seguente:

CODICE IntList:

/* Esempio di astrazione di un IntList (lista di interi). Viene usata una sottoclasse per rappresentare una lista vuota ed
un'altra sottoclasse per implementare la lista non vuota. Il tipo in cima alla gerarchia di tipi è definito da una classe
astratta (IntList) che non ha variabili di istanza e non c'è costruttore.
I metodi toString() ed equals() sono implementati usando l'iteratore elements(). Vengono fornite due definizioni per
il metodo equals() (cioè equals è un metodo overloaded) per aumentare le performance nel caso comune in cui il codice
chiamato controlla l'uguaglianza di due oggetti IntList */

public abstract class IntList{
// OVERVIEW: IntList è una lista immutabile di Object, una tipica IntList è una sequenza: [X1, X2,....,Xn]

// METODI ABSTRACT:

public abstract Object first() throws EmptyException;
// EFFECTS: Se this è vuoto solleva EmptyException, altrimenti ritorna il primo elemento di this

public abstract IntList rest() throws EmptyException;
/* EFFETCTS: Se this è vuoto solleva EmptyException, altrimenti ritorna la lista contenente tutti gli elementi
meno il primo elemento di this nell'ordine originale */

public abstract Iterator elements();
// EFFECTS: Ritorna un generatore che produce gli elementi di this esattamente una volta nell'ordine originale

public abstract IntList addE1(Object x);
// EFFECTS: Aggiungi x all'inizio di this

public abstract int size();
// EFFECTS: Ritorna il numero di elementi presenti in this

public abstract boolean repOK();

// METODI IMPLEMENTATI:

/* public String toString(){
.....
.....
.....
} */

public boolean equals(Object o){
try{
return equals ((IntList) o);
}catch(ClassCastException e){ return false;}
}

/* public booleans equals(IntList o){
.....
.....
.....
} */
}


CODICE EmptyIntList:

public class EmptyIntList extends IntList{ // Questa classe estende la classe astratta IntList

/** COSTRUTTORE
EFFECTS: Crea un nuovo oggetto di tipo EmptyList
@param: void
@return: il riferimento ad un nuovo oggetto di tipo EmptyIntList */
public EmptyIntList(){}; // Viene semplicemente invocato il costrutore della classe padre IntList

public Objcet first() throws EmptyException{
throw new EmptyException("EmptyIntList.first"); // Essendo la lista vuota solleva sempre l'eccezione EmptyIntList
}

public IntList addE1(Object x){
return new FullIntList(x); // Crea una nuova FullIntList passandogli l'elemento che verrà messo in testa
}

public boolean repOK(){
return true;
}

public String toString(){
return "IntList: []";
}

public booleans equals(Object x){
return (x instanceof EmptyList);
}

// Quì và l'implementazione di rest() e di size()

public Iterator elements(){
return new EmptyGen();
}

static private class EmptyGen implements Iterator{
EmptyGen(){ // Costruttore: richiama il costruttore di Iterator
}

public boolean hasNext(){
return false; // Ritorna sempre falso perchè è l'iteratore sulla lista vuota
}

public Object next() throws NoSuchElementException{
throw new NoSuchElementException("IntList.elements");
}
}
}


CODICE FullIntList:

public class FullIntList extends IntList{
private int size;
private Object val;
private IntList next;

/** COSTRUTTORE
EFFECTS: Crea un nuovo oggetto di tipo FullIntList
@param: un Object
@return: il riferimento ad un oggetto di tipo FullIntList */

public FullIntList(Object x){
size = 1; // Quando crea una nuova FullIntList setta ad 1 la dimensione poichè inizialmente conterrà un valore
val = x; // Imposta il campo val col il riferimento all'Object x
next = new EmptyList(); // Fai puntare il campo next ad una nuova lista vuota
}

public Object first(){
return val;
}

public Object rest(){
return next;
}

public IntList addE1(Object x){
FullIntList n = new FullIntList(x);
n.next = this;
n.size = this.size + 1;
return n;
}

// Quì implementazione dei metodi elements(), size(), repOK()
}


Come dicevo il codice è parzialmente implementato.

DOMANDE:

1) Nella classe abstract si dichiara un metodo equals che prende come parametro un Object, lo casta ad IntList e chiama: equals ((IntList) o) che ha dichiarato e di cui non ha implementato il codice...perchè lo fà? Perchè così potrei passargli indistintamente un EmptyIntList così come un FullIntList che vengono convertiti ad IntList e confrontati?

2) Nella classe abstract che senso ha dichiarare il metodo toString() (che fornisce una rappresentazione sotto forma di stringa degli oggetti) se poi lo reimplementa in EmptyIntList? (e perchè non lo ha reimplementato anche in FullIntList)

3) Ma l'eccezione EmptyException in IntList se l'è dichiarata lui da qualche altra parte (che non dice)? perchè il compilatore non la conosce.

4) Ma pare solo a me che l'esempio è fatto un po' alla cavolo sotto vari punti di vista: a partire dalla bruttezza di astrarre una lista vuota ed una lista piena (io forse avrei pensato ad astrarre da una generica lista una lista di interi, una lista di double, una lista di stringhe, etcetc...mi pare più sensata ed utile come cosa).

Grazie
Andrea

Energy++
18-05-2009, 09:27
1) Perchè così potrei passargli indistintamente un EmptyIntList così come un FullIntList che vengono convertiti ad IntList e confrontati? si

2) Nella classe abstract che senso ha dichiarare il metodo toString() (che fornisce una rappresentazione sotto forma di stringa degli oggetti) se poi lo reimplementa in EmptyIntList? (e perchè non lo ha reimplementato anche in FullIntList)
si ha senso, poi lo puoi implementare o non implementare nelle classi derivate (infatti in EmptyIntList è implementato e in FullIntList non è implementato)

3) Ma l'eccezione EmptyException in IntList se l'è dichiarata lui da qualche altra parte (che non dice)? perchè il compilatore non la conosce.
Sicuramente l'ha dichiarata da qualche parte, perchè non si trova nel framework di java

4) Ma pare solo a me che l'esempio è fatto un po' alla cavolo sotto vari punti di vista: a partire dalla bruttezza di astrarre una lista vuota ed una lista piena (io forse avrei pensato ad astrarre da una generica lista una lista di interi, una lista di double, una lista di stringhe, etcetc...mi pare più sensata ed utile come cosa).
beh sicuramente questa gerarchia è stata implementata per fornire soltanto un esempio a grandi linee, non per realizzare qualcosa di veramente funzionale

D4rkAng3l
18-05-2009, 09:37
1) Perchè così potrei passargli indistintamente un EmptyIntList così come un FullIntList che vengono convertiti ad IntList e confrontati? si

2) Nella classe abstract che senso ha dichiarare il metodo toString() (che fornisce una rappresentazione sotto forma di stringa degli oggetti) se poi lo reimplementa in EmptyIntList? (e perchè non lo ha reimplementato anche in FullIntList)
si ha senso, poi lo puoi implementare o non implementare nelle classi derivate (infatti in EmptyIntList è implementato e in FullIntList non è implementato)

3) Ma l'eccezione EmptyException in IntList se l'è dichiarata lui da qualche altra parte (che non dice)? perchè il compilatore non la conosce.
Sicuramente l'ha dichiarata da qualche parte, perchè non si trova nel framework di java

4) Ma pare solo a me che l'esempio è fatto un po' alla cavolo sotto vari punti di vista: a partire dalla bruttezza di astrarre una lista vuota ed una lista piena (io forse avrei pensato ad astrarre da una generica lista una lista di interi, una lista di double, una lista di stringhe, etcetc...mi pare più sensata ed utile come cosa).
beh sicuramente questa gerarchia è stata implementata per fornire soltanto un esempio a grandi linee, non per realizzare qualcosa di veramente funzionale

Ti ringrazio...comunque uno scopo utile delle implementazioni multiple potrebbe essere il seguente?

Dichiaro un'interface Confrontabili da cui implemento varie sottoclassi concrete di oggetti che sono confrontabili tra di loro.

Oppure dichiaro un'interface Lista e vado ad implementare le sottoclassi: IntList, DoubleList, StringList, etcetc

E' questo il senso?

Grazie
Andrea