PDA

View Full Version : [JAVA] Esercizio (base?) su collezioni eterogenee e parametri polimorfi


utrecht
11-08-2003, 23:39
Ho preso da un tutorial un esercizio per imparare il concetto di collezioni eterogenee nonchè paramentri polimorfi.
Lo scopo è di realizzare una classe che stabilisca le paghe dei dipendenti di un'azienda.
Dopo aver definito le classi 'Dipendente', 'Programmatore' e 'Dirigente', le indicazioni fornite sono quelle di utilizzare una collezione eterogenea di dipendenti ed un parametro polimorfo per risolvere il problema in un modo molto semplice, veloce ed elegante.

Tenete presente che il codice sarà pieno di cretinate perchè l'ho scritto io, cercando di venire a capo dell'esercizio (infatti in fase di compilazione ottengo un'errore!) :muro: :muro:
Mi aiutate a correggerlo? GRAZIE!
---

class Dipendente
{
int stipendio;
}
class Programmatore extends Dipendente
{
String cognome;
}

class Dirigente extends Dipendente
{
String orarioLavoro;
}

public class ParametroPolim
{
public void pagaDipendente(Dipendente dip)
{
Dipendente arr[] = new Dipendente [3];
arr[0]=new Dipendente();
arr[1]=new Programmatore();
arr[2]=new Dirigente();

if (dip instanceof Dipendente)
{
dip.stipendio=20;
}
else if (dip instanceof Programmatore)
{
dip.stipendio=500;
}
else
{
dip.stipendio=1000;
}
System.out.println(dip.stipendio);
}
/*
Suggerimento finale dell'autore: "... ora, possiamo chiamare questo metodo all’interno di un ciclo di n iterazioni, passandogli tutti gli elementi della collezione eterogenea, e raggiungere così il nostro scopo:"
. . .
for (int i=0; i<180; i++) //180 era il valore originale degli elementi dell'array
{
pagaDipendente(arr[i]);
. . .
}
*/

//Ed io ho pensato bene di tradurre in quello che segue ma non funziona...
public static void main (String args[])
{
for (int i=0; i<3; i++)
{
ParametroPolim obj =new ParametroPolim();
pagaDipendente(arr[i]);

}
}
}

PGI
12-08-2003, 00:38
Originariamente inviato da utrecht

//Ed io ho pensato bene di tradurre in quello che segue ma non funziona...
public static void main (String args[])
{
for (int i=0; i<3; i++)
{
ParametroPolim obj =new ParametroPolim();
pagaDipendente(arr[i]);

}
}
}



Per testare l'applicazione devi creare (nel main ad esempio) un array di oggetti Dipendente (che recita la parte della collezione eterogenea) di questo tipo:

Dipendente[] dipendenti={
new Dipendente(),
new Dirigente(),
new Programmatore(),
new Dipendente()
};

Sposta la creazione dell'oggetto Parametro Polim "obj" al di fuori del ciclo, cambia la condizione terminale del ciclo da "i<3" a "i<dipendenti.length" e poi passi "dipendent[i]i" come argomento di "pagaDipendenti".

Dovresti ottenere qualcosa così:


public static void main(String[] a) {
Dipendente[] dipendenti={
new Dipendente(),
new Dirigente(),
new Programmatore(),
new Dipendente()
};

ParametroPolim obj =new ParametroPolim();

for(int i=0;i< dipendenti.length;i++) {
obj.pagaDipendente(dipendenti[i]);
}

//per controllare
for(int i=0;i< dipendenti.length;i++) {
System.out.println("Dipendente "+i+" paga: "+dipendente[i].stipendio);
}
}


Non l'ho provato ma dovrebbe funzionare.

L'errore in compilazione è dovuto al fatto che nel sorgente ad "arr[i]" (tradotto: elemento di indice "i" di "arr") non corrisponde un array definito come "arr".

Ciao.

P.S.

Le prime 4 righe del metodo paga dipendente non hanno funzione, puoi cancellarle.

utrecht
12-08-2003, 12:56
Innanzi tutto grazie per la risposta.
Non l'ho provato ma dovrebbe funzionare.
In realtà, ottenevo un errore in fase di compilazione che però, una volta rivisitato (il codice che segue), mi faceva stampare sempre a zero il valore obj.pagaDipendente(dipendenti[i]).
---
public class ParametroPolim
{
public void pagaDipendente(Dipendente dip)
{
if (dip instanceof Dipendente)
{
dip.stipendio=20;
}
else if (dip instanceof Programmatore)
{
dip.stipendio=500;
}
else
{
dip.stipendio=1000;
}
System.out.println(dip.stipendio);
}

public static void main(String[] args)
{
Dipendente dipendenti [] =
{
new Dipendente(),
new Dirigente(),
new Programmatore(),
};

ParametroPolim obj =new ParametroPolim();

//per controllare
for(int i=0;i<dipendenti.length;i++)
{System.out.println("Dipendente "+i+" paga: "+obj.pagaDipendente(dipendenti[i]));}
}

}

... allora ho modificato il valore di ritorno del metordo pagaDipendente in
public int pagaDipendente(Dipendente dip)
{
. . .
return dip.stipendio;
}

ma mi restituisce sempre il valore '20', gli altri vengono ignorati........:muro:

Nessun 'aiutino'?

utrecht
12-08-2003, 13:34
......ora funziona!! Magari potrebbe anche non fregarvene niente ma la sintassi corretta all'interno del metodo pagaDipendente è:
. . .
if (dip instanceof Dipendente)
{
dip.stipendio=20;
}
if (dip instanceof Programmatore)
{
dip.stipendio=500;
}
if (dip instanceof Dirigente)
{
dip.stipendio=1000;
}
return dip.stipendio;
/* anche se non mi sembra elegantissimo! */
. . .

anzichè
. . .
if (dip instanceof Dipendente)
{
dip.stipendio=20;

}
else if (dip instanceof Programmatore)
{
dip.stipendio=500;

}
else
{
dip.stipendio=1000;
}
return dip.stipendio;
. . .

Certo è che non riesco a capire perchè nel primo caso non mi viene valutata correttamente l'intera espressione condizionale....... :(

PGI
12-08-2003, 14:25
Originariamente inviato da utrecht
Certo è che non riesco a capire perchè nel primo caso non mi viene valutata correttamente l'intera espressione condizionale....... :(
Da occhio di falco quale sono non l'avevo notato...l'età! :D Beh, non si chi sia l'autore dell'esempio che hai seguito ma quello non è il paradiso dell'efficenza.

Perchè "if" si "else if" no?

Per dirla con una metafora,l'operatore "instanceof" restituisce "true" non quando l'elemento (oggetto) a sinistra appartiene al modello (classe) a destra ma, più genericamente, se l'elemento a sinistra si trova in un ramo "inferiore" dell'albero genealogico a cui appartiene l'elemento-classe di destra.

Programmatore e Dirigente sono tutti "figli" di Dipendente.

Per questo in un array di oggetti i cui elementi siano tutti figli o istanze di Dipendente "array[i] instanceof Dipendente" sarà sempre "true"

Poichè in una serie di condizionali "if...else if..." il secondo viene preso in considerazione solo se il primo sia falso ecco che ad ogni elemento dell'array viene assegnato lo stipendio da "Dipendente"

Con una serie if...if invece quello che fai è una sorta di "scrematura" successiva in cui il primo if è sempre vero e il secondo-terzo possono essere vero o falso. Apparentemente il programma funziona, ma solo se nel codice sorgente si rispetta un ordine definito nella serie di "if...instanceof"

Ma cosa succederebbe se decidessi di aggiungere un terzo modello di Dipendente, "figlio" di Dirigente, magari un "DirigenteDiSecondoLivello"? Si riproporrebbe lo stesso problema, perchè le verifiche su un Dirigente restituirebbero "true" anche sul nuovo (e diverso) dirigente. Ecco allora che la tua serie di if si arricchirebbe di un ulteriore elemento che ad ogni esecuzione del cilclo carica di lavoro il processore.

Per farla breve, tra vettori eterogenei e parametri polimorfici (nomi altisonanti, nascondono concetti elementari) alla fine abbiamo perso di vista le basi dell'ereditarietà. Se vuoi una soluzione alternativa fai un fischio, ma non credo sia necessario perchè l'esercizio era sui parametri polimorfici (tradotto è "passare un oggetto come parametro", nulla di più, che sia polimorfico è conseguenza dell'ereditarietà) e collezioni eterogenee (tanto per saperlo non c'è un bel nulla di eterogeneo, lo sarebbe invece se fosse un insieme di primitivi e oggetti).

Per curiosità chi è l'autore del libro che stai leggendo?

Ciao.

utrecht
12-08-2003, 18:13
Nel dubbio (non voglio scatenare polemiche ;)) l'ho postato in pvt

PGI
12-08-2003, 19:30
Dal basso della mia esperienza lo trovo un ottimo manuale (bello condensato però!)

A fini d'esempio sul "polimorfismo" il codice del capitolo 6 è valido (nota che la classe Dipendente non viene mai usata direttamente ma solo come modello "astratto". Evito di essere "verboso", comunque quel particolare rende coerente il codice inserito nel manuale)

Ciao.

utrecht
14-08-2003, 09:44
..... complimenti per la chiarezza e la semplicità con la quale ti spieghi!
Aggiungo che ho in realtà anche un tomo sul quale cerco di studiare: "Thinking in Java" di Bruce Eckel.

Approfitto della tua preparazione e della tua disponibiltà. Tempo fa avevo chiesto su un forum concorrente dove poter reperire esercizi, magari con difficoltà crescente e con annesse soluzioni, in maniera tale da testare non solo il mio grado di preparazione ma anche per comprendere come debba essere affrontato l'approccio ad un problema (soprattutto mi interesserebbe vedere del codice sorgente scritto da persone competenti). La risposta è stata "... cerca in rete".
Riesce a fornirmi qualche coordinata più precisa? Grazie.

E comunque non è detto che in futuro io non torni a massacrarti con qualche altre quesito :D :D

PGI
14-08-2003, 13:34
Se hai "thinking in java" potresti fare un pensierino sull'acquisto (20$, pagamento con carta di credito) della guida annotata alla soluzione degli esercizi proposti nel manuale di Bruce Eckel (link (http://www.mindview.net/Books/TIJ/Solutions/orderForm)].

Per la verità è l'unica serie esercizi-soluzioni di cui io abbia notizia.

Ho provato a fare una rapida ricerca su google con "raccolta esercizi java"; è facile rendersi conto di quanto sia poco utile la risposta "cerca in rete"

Per esempi di codice, un tempo c'era una bella rubrica su mokabyte (http://www.mokabyte.com/mokacode/index.htm), attualmente è off-line per "aggiornamento" (?), non so quando tornerà in linea..

Dubbi e curiosità sono sempre risolubili su questo forum, c'è un bel gruppo di persone disponibili a condividere un po' si "sapere" :)

Ciao.