2012-02-20 6 views
10

Sto cercando di trovare un buon esempio per l'utilizzo dell'ereditarietà multipla, cosa non può essere fatto con le normali interfacce.Eredità multipla: quale è un buon esempio?

Penso che sia piuttosto difficile trovare un tale esempio che non possa essere modellato in un altro modo.

Edit: Voglio dire, qualcuno può nominarmi un buon esempio del mondo reale di quando si ha bisogno di usare l'ereditarietà multipla per implementare questo esempio il più pulito possibile. E non dovrebbe fare uso di più interfacce, proprio come è possibile ereditare più classi in C++.

+1

Hai accettato [risposta di Luchian Grigore] (http://stackoverflow.com/a/9360014/2932052), ma sei davvero soddisfatto? Penso che questa sia una buona domanda (+1), ma forse non per SO, perché potrebbe non avere una risposta reale che possa convincere il programmatore critico. – Wolf

+1

Non sono molto soddisfatto. Ho dovuto discutere con un programmatore critico nel corso della giornata e non gli piaceva l'argomento. Ho semplicemente rinunciato ad essere sincero: D –

+0

Quindi è forse meglio non accettare la "risposta" che non è altro che una citazione sparsa decorata di un (povero) esempio di Wikipedia. Forse ci sarà qualcuno con una vera risposta in futuro - no, molto probabilmente non io :-) – Wolf

risposta

7

Quanto segue è un classico:

class Animal { 
public: 
    virtual void eat(); 
}; 

class Mammal : public Animal { 
public: 
    virtual void breathe(); 
}; 

class WingedAnimal : public Animal { 
public: 
    virtual void flap(); 
}; 

// A bat is a winged mammal 
class Bat : public Mammal, public WingedAnimal { 
}; 

Fonte: wiki.

+1

Questo è fatto con le interfacce, non voglio qualcosa che faccia uso dell'ereditarietà della classe FULL come è possibile in C++. –

+0

@ PhilippSpieß quali sono le interfacce? –

+0

@ PhilippSpieß anche, che cos'è l'ereditarietà completa? –

2

Un esempio in cui l'ereditarietà di classi multiple ha senso è il pattern Observer. Questo schema descrive due attori, l'osservatore e l'osservabile, e il primo vuole essere avvisato quando quest'ultimo cambia lo stato dell'oggetto.

Una versione semplificata di notifica client può apparire come questo in C#:

public abstract class Observable 
{ 
    private readonly List<IObserver> _observers = new List<IObserver>(); 

    // Objects that want to be notified when something changes in 
    // the observable can call this method 
    public void Subscribe(IObserver observer) 
    { 
     _observers.Add(observer); 
    } 

    // Subclasses can call this method when something changes 
    // to notify all observers 
    protected void Notify() 
    { 
     foreach (var observer in _observers) 
      observer.Notify(); 
    } 
} 

Questa in sostanza è la logica di base è necessario informare tutti gli osservatori registrati. È possibile rendere qualsiasi classe osservabile derivando da questa classe, ma poiché C# supporta solo l'ereditarietà di una singola classe, si è limitati a non derivare da un'altra classe. Qualcosa del genere non avrebbe funzionato:

public class ImportantBaseClass { /* Members */ } 

public class MyObservableSubclass : ImportantBaseClass, Observable { /* Members */ } 

In questi casi si deve spesso di replicare il codice che fa sottoclassi osservabili in tutti loro, in fondo violare la non ripetere te stesso e l'unico punto di principi di verità (se hai fatto MVVM in C#, pensaci: quanto spesso hai implementato l'interfaccia INotifyPropertyChanged?). Una soluzione con eredità di classe multipla sarebbe molto più pulita a mio parere. In C++, l'esempio sopra sarebbe compilato bene.

Uncle Bob wrote an interesting article about this, da cui ho tratto l'esempio. Ma questo problema si applica spesso a tutte le interfacce che sono * in grado (eg confrontabile, equabile, enumerabile, ecc.): Una versione di ereditarietà di classi multiple è spesso più pulita in questi casi, come affermato da Bertrand Meyer nel suo libro "Object-Oriented Software Construction ".