[Java] Ereditarietà multipla e interfacce

Messaggioda Crypto1993 » 17/04/2014, 15:09

Buonasera a tutti, volevo chiedere il vostro aiuto sperando possiate risolvere un dubbio che ho da diversi giorni circa il problema dell'ereditarietà multipla in Java. Vi espongo sinteticamente il testo di una prova di esame del corso di Programmazione orientata agli oggetti che sto attualmente seguendo: la prova chiede che venga realizzata un'applicazione Java che sia in grado di memorizzare su un apposito file delle informazioni su delle persone. In realtà, il testo afferma che esistono persone "semplici", studenti, lavoratori e studenti lavoratori, specificando che ogni persona possiede delle proprietà quali nome, cognome, indirizzo..., mentre uno studente si differenzia dal lavoratore perché il primo ha una variabile matricola, a cui è associato il metodo getter getMatricola(), ed un hashmap che funge da libretto universitario (sulla cui gestione, in verità, non mi soffermo non essendo attualmente questo il problema), mentre il secondo ha solamente un attributo salario con un metodo getSalario() associato.
Il mio dubbio è relativo essenzialmente alla modellazione, ed in effetti la via più immediata sarebbe quella di creare una classe StudenteLavoratore che estende sia la classe Studente che la classe Lavoratore, ma ciò è impossibile (in Java). Allora ho tentato di risolvere l'arcano nel modo seguente: dato che ogni Studente, ogni Lavoratore ed ogni StudenteLavoratore è una Persona, creo una classe Persona che contempli i dati comuni a ciascun tipo di agente, dopodiché definisco una classe Studente, derivata da Persona, a cui aggiungo tutte le sue caratteristiche, ed un'interfaccia che chiamo IWorker, contemplante solo il metodo getSalario(); successivamente, definisco la classe Lavoratore come estensione di Persona che implementa IWorker, ed infine creo StudenteLavoratore come classe derivata di Studente implementante IWorker.
Ora, facendo in questo modo, nella classe StudenteLavoratore ho accesso all'hashmap e alla matricola, ma ho necessità di ridefinire una variabile salario, mentre io vorrei che gli attributi tipici di Studente e di Lavoratore venissero "inseriti" automaticamente in StudenteLavoratore, dando l'impressione che si tratti di una vera e propria ereditarietà multipla di classe.

Come potrei risolvere questo problema?
Crypto1993
New Member
New Member
 
Messaggio: 17 di 52
Iscritto il: 04/03/2010, 17:42

Re: [Java] Ereditarietà multipla e interfacce

Messaggioda Luc@s » 17/04/2014, 15:51

Lavora con interfaccie.
E volutamente cosi' Java.
----
Luca Francesca <[email protected]>
System Engineer Lead @ Salesforce

Info: https://www.linkedin.com/in/lucafrancesca/
Luc@s
Senior Member
Senior Member
 
Messaggio: 1280 di 1955
Iscritto il: 01/05/2006, 17:21
Località: Irlanda

Re: [Java] Ereditarietà multipla e interfacce

Messaggioda Crypto1993 » 17/04/2014, 19:49

Sì, questo l'avevo capito. Ma il mio quesito è diverso (forse non mi sono spiegato correttamente, e per questo me ne scuso). Vi posto il codice che ho scritto:

Classe Persona
Codice:
public class Persona
{
    protected String nome, cognome, indirizzo, mail, codFisc;
    protected int età;
   
    public Persona(String nome, String cognome, String indirizzo, String mail, String codFisc, int età)
    {
        this.nome = nome;
        this.cognome = cognome;
        this.indirizzo = indirizzo;
        this.mail = mail;
        this.codFisc = codFisc;
        this.età = età;
    }
    public void getInfo()
    {
        System.out.println("NOME = " + this.nome);
        System.out.println("COGNOME = " + this.cognome);
        System.out.println("INDIRIZZO = " + this.indirizzo);
        System.out.println("MAIL = " + this.mail);
        System.out.println("CODICE FISCALE = " + this.codFisc);
        System.out.println("ETA' = " + this.età);
    }
}

Classe Studente
Codice:
public class Studente extends Persona
{
    private final String matricola;
   
    public Studente(String nome, String cognome, String indirizzo, String mail, String codFisc, String matricola, int età)
    {
        super(nome, cognome, indirizzo, mail, codFisc, età);
        this.matricola = matricola;
    }
    public String getMatricola(){ return this.matricola; }
    @Override
    public void getInfo()
    {
        super.getInfo();
        System.out.println("MATRICOLA = " + this.getMatricola());
    }
}

Interfaccia IWorker
Codice:
public interface IWorker
{
    /**
     *
     * @return
     */
    public double getSalario();
}

Classe Lavoratore
Codice:
public class Lavoratore extends Persona implements IWorker
{
    private double salario;
   
    public Lavoratore(String nome, String cognome, String indirizzo, String mail, String codFisc, double salario, int età)
    {
        super(nome, cognome, indirizzo, mail, codFisc, età);
        this.salario = salario;
    }
    @Override
    public double getSalario(){ return this.salario; }   
    @Override
    public void getInfo()
    {
        super.getInfo();
        System.out.println("SALARIO = " + this.getSalario());
    }
}

Classe StudenteLavoratore
Codice:
public class StudenteLavoratore extends Studente implements IWorker
{
    double salario;
   
    /**
     *
     * @param nome
     * @param cognome
     * @param indirizzo
     * @param mail
     * @param codFisc
     * @param matricola
     * @param salario
     * @param età
     */
    public StudenteLavoratore(String nome, String cognome, String indirizzo, String mail, String codFisc, String matricola, double salario, int età)
    {
        super(nome, cognome, indirizzo, mail, codFisc, matricola, età);
        this.salario = salario;
    }
    @Override
    public double getSalario(){ return this.salario; }
    @Override
    public void getInfo()
    {
        super.getInfo();
        System.out.println("SALARIO = " + this.getSalario());
    }
}


Ora, la domanda è: è possibile, all'interno di StudenteLavoratore, ricavare gli attributi delle classi Studente e Lavoratore, pur essendo derivata solamente dalla prima delle due?
Crypto1993
New Member
New Member
 
Messaggio: 18 di 52
Iscritto il: 04/03/2010, 17:42

Re: [Java] Ereditarietà multipla e interfacce

Messaggioda Crypto1993 » 21/04/2014, 16:54

UP!
Crypto1993
New Member
New Member
 
Messaggio: 19 di 52
Iscritto il: 04/03/2010, 17:42

Re: [Java] Ereditarietà multipla e interfacce

Messaggioda giuscri » 21/04/2014, 21:57

L'ereditarieta' multipla non e' consentita in Java. O fai in modo che `StudenteLavoratore` erediti anche lui da `Persona` e bona, oppure opta per una soluzione stravagante

Codice:
// Persona.java
public class Persona {

    private String nome, cognome, ...;

    ...

}


Codice:
// Lavoratore.java
public class Lavoratore extends Persona {

    private int salario;

    public Lavoratore(nome, cognome, ..., salario) {
        ...
        this.salario = salario;
    }

    public int getSalario() {
        return this.salario;
    }
}


Codice:
// Studente.java
public class Studente extends Lavoratore {

    private int numeroMatricola;

    public Studente(nome, cognome, ..., numeroMatricola) {
        super(nome, cognome, ..., 0);
        this.numeroMatricola = numeroMatricola
    }

    ...

}


Codice:
// StudenteLavoratore.java
public class StudenteLavoratore extends Studente {

    public StudenteLavoratore(nome, cognome, ..., salario, numeroMatricola) {
        this.nome = nome;
        ...
        this.salario = salario; // In generale, non nullo ...
        this.numeroMatricola = numeroMatricola;
    }

    ...

}


A patto di documentare abbastanza la tua scelta, e cioe' che lo studente e' pensato a tutti gli effetti come un lavoratore ...non pagato. :lol:
"Non c'è cosa peggiore del talento sprecato"
"Amazingly non-intuitive. If you've problems with this: you're not alone."
La matematica È tosta.
\[F(n) = 4F(n -3) + F(n -6) \]
giuscri
Senior Member
Senior Member
 
Messaggio: 859 di 1720
Iscritto il: 29/05/2011, 22:22

Re: [Java] Ereditarietà multipla e interfacce

Messaggioda Crypto1993 » 22/04/2014, 13:20

Ti ringrazio per la risposta, però temo che non corrisponda effettivamente a quel che speravo :(
Il problema è che voglio distinguere logicamente le figure di Studente e di Lavoratore, ma pur nella loro radice comune (Persona) devono essere in grado di dar luce a StudenteLavoratore. Ora, se i meccanismi dell'ereditarietà non me lo consentono, avevo pensato di far uso delle interfacce, ma queste non mi consentono altro che impostare le signature dei metodi astratti che andranno implementati, senza ch'io abbia la possibilità di "mettere a comune" attributi di due classi disgiunte.
Crypto1993
New Member
New Member
 
Messaggio: 20 di 52
Iscritto il: 04/03/2010, 17:42

Re: [Java] Ereditarietà multipla e interfacce

Messaggioda apatriarca » 22/04/2014, 15:24

Esistono diversi metodi per modellare questo tipo di situazioni e l'ereditarietà è raramente il modo migliore per farlo. Vediamo un paio di soluzioni:
1. Creare delle classi Lavoro e Studio. La prima classe sarà responsabile di gestire le informazioni sul lavoro di una persona. In particolare conterrà un campo per lo stipendio percepito. La classe studio si occuperà invece di contenere le informazioni sull'iscrizione scolastica/universitaria per cui conterrà la matricola dello studente. La classe persona conterrà poi delle istanze di queste classi. Se l'istanza della classe Lavoro è non nulla, allora la persona sarà un lavoratore o studente lavoratore e se la classe Studio sarà non nulla la persona sarà Studente o Studente Lavoratore. In questo modo si può anche facilmente ad esempio passare a situazioni in cui la persona abbia più lavori.
2. Siccome devi memorizzare su file.. Puoi anche semplicemente creare 3 array. Nel primo array ci sono le persone. Ad ogni persona è associato un valore univoco per rappresentarla. Negli altri due array ci sono puoi i lavori e gli studi intrapresi dalle persone. Ogni lavoro conterrà l'identificativo della persona e quanto prende e ogni studio conterrà l'identificativo della persona e la sua matricola. Al posto di un array puoi ovviamente anche usare altre strutture dati come Mappe..
apatriarca
Moderatore
Moderatore
 
Messaggio: 3391 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [Java] Ereditarietà multipla e interfacce

Messaggioda Crypto1993 » 22/04/2014, 16:10

Perdonami, ma come gestisci le tre classi? Nidificando Lavoro e Studio in Persona, o cosa?
Onestamente, la scelta dei tre array mi pare un po' troppo semplicistica (vorrei, più che altro, lavorare in modo da sfruttare appieno la programmazione a oggetti; se la mia prof. vede un listato fatto così mi fulmina con tutto il computer).
E poi: ammettiamo che venga esplicitamente richiesto di procedere mediante interfacce (o, eventualmente classi astratte; la mia prof. afferma che sono questi i metodi più importanti per ovviare al problema dell'ereditarietà, almeno dal punto di vista logico). Il problema è quello che ho posto inizialmente: riesco a lavorare coi metodi, ma sono costretto a ridefinirmi una variabile.
Crypto1993
New Member
New Member
 
Messaggio: 21 di 52
Iscritto il: 04/03/2010, 17:42

Re: [Java] Ereditarietà multipla e interfacce

Messaggioda apatriarca » 22/04/2014, 16:32

La soluzione con gli array è una soluzione da database relazionale. Se dovessi infatti implementare quella richiesta usando un database, useresti tre tabelle come ho descritto nel mio precedente post. È probabilmente possibile implementare il tutto in modo un po' più "ad oggetti" e se vuoi ti mostro il codice corrispondente.

La prima soluzione usa invece la composizione. La composizione è molto spesso preferibile all'ereditarietà in quanto molto più flessibile. Permette infatti di gestire più facilmente le situazioni in cui hai diverse "proprietà" di un oggetto che possono presentarsi in modo indipendente l'una dalle altre come in questo caso.

L'uso delle interfacce ti permette di lavorare con le classi Lavoratore e StudenteLavoratore oppure Studente e StudenteLavoratore nello stesso modo (a patto di limitarsi alle funzionalità comuni), ma è comunque necessario reimplementare le stesse funzionalità in più classi. Non è insomma possibile l'implementazione della classe Studente o di Lavoratore in StudenteLavoratore. Non si tratta di una soluzione ottimale, solo un modo per usare l'ereditarietà in una situazione in cui altri metodi sarebbero preferibili.
apatriarca
Moderatore
Moderatore
 
Messaggio: 3392 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [Java] Ereditarietà multipla e interfacce

Messaggioda Crypto1993 » 23/04/2014, 21:16

In pratica sarebbe a dire: definiamo la classe StudenteLavoratore per mezzo di istanze di Studente e Lavoratore interne alla classe stessa? Cioè:

Codice:
public class StudenteLavoratore
{
    private Studente S;
    private Lavoratore L;

    public StudenteLavoratore(...){ ... }
}


E se provassi pensando StudenteLavoratore come classe astratta che estende Persona e cui definire Studente e Lavoratore, specializzando dove occorre?
Crypto1993
New Member
New Member
 
Messaggio: 22 di 52
Iscritto il: 04/03/2010, 17:42

Prossimo

Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite

cron