У C ++ клас може успадковувати (прямо чи опосередковано) більш ніж один клас, який називається
множинним успадкуванням .
Однак C # і Java обмежують класи на одинакове успадкування, кожен клас успадковує від одного батьківського класу.
Багатократне успадкування є корисним способом створення класів, що поєднують аспекти двох розрізнених ієрархій класів, що часто трапляється при використанні різних рамок класів у межах однієї програми.
Якщо дві рамки визначають власні базові класи для винятку, наприклад, ви можете використовувати декілька успадкувань для створення класів виключень, які можна використовувати з будь-яким фреймворком.
Проблема багаторазового успадкування полягає в тому, що це може призвести до неоднозначності. Класичний приклад - коли клас успадковує від двох інших класів, кожен з яких успадковує той самий клас:
class A {
protected:
bool flag;
};
class B : public A {};
class C : public A {};
class D : public B, public C {
public:
void setFlag( bool nflag ){
flag = nflag; // ambiguous
}
};
У цьому прикладі flag
член даних визначається за допомогою class A
. Але class D
сходить class B
і class C
, які обидва походять з A
, так що по суті дві копії з flag
доступні , тому що два примірника A
в D
ієрархії класів «S. Який ви хочете встановити? Компілятор поскаржиться, що посилання на flag
в D
- неоднозначне . Одне виправлення полягає в тому, щоб явно розмежувати посилання:
B::flag = nflag;
Ще одне виправлення полягає в оголошенні B і C як virtual base classes
, що означає, що в ієрархії може існувати лише одна копія A, усуваючи будь-яку неоднозначність.
Інші складності існують з багаторазовим успадкуванням, наприклад, в якому порядку ініціалізуються базові класи при побудові похідного об'єкта, або спосіб ненавмисного приховування членів від похідних класів. Щоб уникнути цих складностей, деякі мови обмежуються простою єдиною моделлю успадкування.
Хоча це значно спрощує успадкування, воно також обмежує його корисність, оскільки тільки класи з загальним предком можуть поділяти поведінку. Інтерфейси дещо пом'якшують це обмеження, дозволяючи класам в різних ієрархіях виставляти загальні інтерфейси, навіть якщо вони не реалізовані за допомогою коду обміну.