Sostituzione dell'ereditarietà multipla con delega

1

Stavo passando per "Object Oriented Modeling and Design" di James Rumbaugh e altri, e ha detto che nelle lingue in cui l'ereditarietà multipla non è supportata come Java, tre meccanismi possono essere usati come soluzioni alternative

  1. Delega mediante aggregazione di ruoli
  2. Eredita la più importante
  3. classe e delegare il resto Generalizzazione annidata

Non riuscivo a capire gli esempi forniti nel testo. Qualcuno potrebbe spiegarlo con un esempio. So che il "problema dei diamanti" è un problema all'interno dell'ereditarietà multipla e java supporta l'ereditarietà multipla delle interfacce.

    
posta user5507 07.08.2012 - 05:51
fonte

2 risposte

3

La mia osservazione è che molte persone usano impropriamente l'ereditarietà multipla senza lavorare attraverso le domande sul tipo di composizione.

L'esempio OO "classico" di un'auto porta a questo problema. Ad esempio, diremo che un'auto si divide nelle seguenti parti:

  • è un veicolo
  • ci sono gli pneumatici
  • c'è un motore
  • c'è uno chassis
  • ci sono posti
  • e così via ...

quindi definiremo una classe simile a questa:

 public class Car : Vehicle, Tires, Engine, Chassis, Seats {}

Tutto bene, ma presenta alcuni problemi significativi con l'incapsulamento e costruttori / distruttori. E non rappresenta esattamente l'aspetto di un'auto nel mondo reale.

Se iniziamo a fare domande sulla composizione, vedremo alcune sfumature che all'inizio non erano ovvie.

  • è un'auto un veicolo? (Sì)
  • è un'auto un pneumatico o una serie di pneumatici? (no, ha un set di pneumatici)
  • è un'auto un motore? (No)
  • è un'auto un posto? (No)
  • ecc.

Quindi ora la nostra classe può apparire in questo modo:

public class Car : Vehicle
{
   public Tires tires;  //ie, myCar _has_ a set of tires.
   protected Engine engine;
   private Chassis chassis;
   protected Seats seats;
}

Che è anche tutto bene. Ma ora iniziamo a grattarci la testa e diciamo "sai, mi piacerebbe davvero che quando istanzio un'auto che debba avere pneumatici, un motore e un telaio."

Quindi ora possiamo trasformare gli pneumatici, il motore e lo chassis in interfacce e avremo la seguente classe. Sto prefiggendo le interfacce con "I" per rendere più chiara la distinzione.

public class Car : Vehicle, ITires, IEngine, IChassis
{
   protected Seats seats;
}

Le interfacce sono come i contratti. Quando una classe implementa un'interfaccia, garantisce che fornirà determinati metodi e comportamenti.

E ora le cose vanno davvero bene. Il nostro modello dell'automobile riflette accuratamente la rappresentazione del mondo reale dello stesso oggetto, incluse alcune garanzie sulla somiglianza tra le due forme di cortesia delle interfacce. Abbiamo evitato i problemi icky che l'ereditarietà multipla può creare.

Questo non vuol dire che l'ereditarietà multipla sia sempre cattiva. Tuttavia, non è davvero necessario la maggior parte del tempo, motivo per cui linguaggi come Java e C # non consentono l'ereditarietà multipla.

    
risposta data 07.08.2012 - 16:38
fonte
0

Java non fornisce ereditarietà multipla. Le interfacce non sono infatti ereditate perché sono implementate / realizzate. L'ereditarietà viene utilizzata per estendere una classe di caratteristiche statiche e dinamiche, con composizione (delega, aggregazione) i comportamenti di una classe vengono estesi aggiungendo istanze di classi (attributi, riferimenti) che può utilizzare per eseguire i servizi che fornisce. Ad esempio se hai una classe per un thread che ha bisogno di un socket puoi fare in modo che la classe Thread estenda la classe Socket (decisione molto cattiva) e usi il metodo che eredita o rendi la classe Thread proprietaria di un oggetto Socket che può usare e delegare a è roba da socket. Stesso comportamento architettura molto diversa.

    
risposta data 07.08.2012 - 07:25
fonte