Множественное наследование: что является хорошим примером? - PullRequest
10 голосов
/ 20 февраля 2012

Я пытаюсь найти хороший пример использования множественного наследования, чего нельзя сделать с обычными интерфейсами.

Я думаю, довольно трудно найти такой пример, который нельзя смоделировать другим способом.

Редактировать: Я имею в виду, может ли кто-нибудь назвать меня хорошим примером того, когда вам НУЖНО использовать множественное наследование, чтобы реализовать этот пример как можно более чистым. И он не должен использовать несколько интерфейсов, просто как вы можете наследовать несколько классов в C ++.

Ответы [ 2 ]

9 голосов
/ 20 февраля 2012

Классика:

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

Источник: вики .

2 голосов
/ 02 июля 2015

Одним из примеров, когда имеет смысл наследование нескольких классов, является шаблон Observer.Этот шаблон описывает двух действующих лиц, наблюдателя и наблюдаемого, и первый хочет получить уведомление, когда последний изменит свое состояние объекта.

Упрощенная версия для уведомления клиентов может выглядеть следующим образом в 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();
    }
}

По сути, это основная логика, которую вы должны уведомить всех зарегистрированных наблюдателей.Вы можете сделать любой класс наблюдаемым, производным от этого класса, но, поскольку C # поддерживает только наследование одного класса, вы ограничены в том, чтобы не наследовать от другого класса.Как-то так не получится:

public class ImportantBaseClass { /* Members */ }

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

В этих случаях вам часто приходится копировать код, который делает подклассы наблюдаемыми во всех из них, в основном нарушая принцип «Не повторяйся» и «Единую точку истины».принципы (если вы делали MVVM в C #, подумайте об этом: как часто вы реализуете интерфейс INotifyPropertyChanged?).По моему мнению, решение с наследованием нескольких классов будет намного чище.В C ++ приведенный выше пример компилируется просто отлично.

Дядя Боб написал интересную статью об этом , откуда я взял пример.Но эта проблема часто применяется ко всем интерфейсам, которые * могут (например, сопоставимы, уравниваемы, перечислимы и т. Д.): Версия наследования нескольких классов в этих случаях часто чище, как сказал Бертран Мейер в своей книге «Построение объектно-ориентированного программного обеспечения»».

...