2012-02-20 10 views
10

Próbuję znaleźć dobry przykład do korzystania z dziedziczenia wielokrotnego, czego nie można zrobić ze zwykłymi interfejsami.Wiele dziedziczenia: Jaki jest dobry przykład?

Myślę, że ciężko jest znaleźć taki przykład, którego nie można zmodelować w inny sposób.

Edycja: Chodzi mi o to, czy ktoś może nazwać mnie dobrym przykładem z życia, kiedy POTRZEBUJESZ korzystać z dziedziczenia wielokrotnego, aby zaimplementować ten przykład tak czysto, jak to tylko możliwe. I nie powinno korzystać z wielu interfejsów, tak jak można dziedziczyć wiele klas w C++.

+1

Zaakceptowałeś [odpowiedź Luchiana Grigore] (http://stackoverflow.com/a/9360014/2932052), ale czy jesteś naprawdę zadowolony? Myślę, że jest to bardzo dobre pytanie (+1), ale może nie dla SO, ponieważ może nie mieć prawdziwej odpowiedzi, która może przekonać krytycznego programistę. – Wolf

+1

Nie jestem bardzo zadowolony. W ciągu dnia musiałem się spierać z programistą i nie spodobał mu się argument. Po prostu podałem to szczerze: D –

+0

To może lepiej nie akceptować "odpowiedzi", która jest niczym innym, jak rzadkim, udekorowanym cytatem z (biednego) przykładu Wikipedii. Być może w przyszłości będzie ktoś z prawdziwą odpowiedzią - nie, najprawdopodobniej nie ja :-) – Wolf

Odpowiedz

7

Poniżej znajduje się klasyczny:

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 { 
}; 

Źródło: wiki.

+1

Robi się to z interfejsami, nie mam czegoś, co korzysta z dziedziczenia FULL, jak to jest możliwe w C++. –

+0

@ PhilippSpieß, które są interfejsy? –

+0

@ PhilippSpieß także, co jest dziedziczeniem z pełną klasą? –

2

Jednym z przykładów, w których dziedziczenie wielu klas ma sens, jest wzorzec Obserwator. Ten wzór opisuje dwóch aktorów, obserwatora i obserwowalnego, a pierwszy chce być powiadomiony, gdy ten drugi zmienia swój stan obiektu.

Uproszczona wersja powiadamiania klientów może wyglądać to w 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(); 
    } 
} 

To w zasadzie jest logika rdzeń trzeba zawiadomić wszystkich zarejestrowanych obserwatorów. Możesz uczynić dowolną klasę możliwą do zaobserwowania, wywodząc ją z tej klasy, ale ponieważ C# obsługuje tylko dziedziczenie pojedynczej klasy, jesteś ograniczony do tego, aby nie pochodzić z innej klasy. Coś takiego nie będzie działać:

public class ImportantBaseClass { /* Members */ } 

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

w tych przypadkach często trzeba powtórzyć kod, który sprawia, że ​​podklasy obserwowalne w każdym z nich, w zasadzie naruszono opcję Nie powtarzaj się i jednopunktowy zasad prawdy (jeśli zrobiłeś MVVM w języku C#, zastanów się: jak często implementowałeś interfejs INotifyPropertyChanged?). Rozwiązanie z dziedziczeniem wielokrotnym byłoby moim zdaniem znacznie czystsze. W C++ powyższy przykład kompilowałby się dobrze.

Uncle Bob wrote an interesting article about this, to tutaj otrzymałem przykład. Ale ten problem często dotyczy wszystkich interfejsów, które są * w stanie (np. Porównywalne, dające się porównać, przeliczalne, itp.): Wersja dziedzicząca wielu klas jest często czystsza w tych przypadkach, jak stwierdził Bertrand Meyer w swojej książce "Object-Oriented Software Construction" ".