Есть два разных понятия: интерфейсы и наследование. По сути, это два разных вопроса. Один из них «Как я хочу взаимодействовать с этим объектом?» (интерфейс). Второй: «Как этот объект работает внутри?» (Наследование).
В классических примерах ООП рассмотрим базовый класс:
class Shape {
virtual void draw();
virtual int size();
}
Это интерфейс, он определяет, как вы работаете с разными фигурами. Теперь рассмотрим это:
class Square : Shape {
...
}
class Circle : Shape {
...
}
Хотя интерфейсы для этих двух классов будут одинаковыми (draw () и size ()), реализации не будут иметь ничего общего. Действительно ли код рисования для круга вообще имеет отношение к коду рисования для квадрата? Нет, они просто имеют одинаковое имя и желаемый результат.
Причина, по которой я привожу это, состоит в том, что если вы хотите, чтобы некоторые классы наследовали некоторые члены других классов, то у вас может быть проблема, что вы путаете наследование с интерфейсами. AFAIK, C ++ не поддерживает интерфейсы (я, вероятно, ошибаюсь по этому поводу). Но вы могли бы подделать это с помощью «чисто виртуальных» классов (например, Shape выше).
class Shape {
virtual void draw();
}
class EdgyShape : Shape {
virtual int width();
virtual int height();
}
class RoundyShape : Shape {
virtual int radius();
}
Теперь у вас есть интерфейсы с иерархией, но нет реализации вообще.
class Circle : RoundyShape {
...
}
class Rectangle : EdgyShape {
...
}
class Square : Rectangle {
...
}
То есть, у Circle и Rectangle нет общего кода, а у Rectangle и Square нет. И все 3 используют один и тот же базовый интерфейс Shape с некоторыми дополнениями в зависимости от типа.
Может быть, это проливает свет на то, как реорганизовать классовую иерархию, чтобы вы могли лучше разделить их?