Множественное наследование


Мно́жественное насле́дование — свойство, поддерживаемое частью объектно-ориентированных языков программирования, когда класс может иметь более одного суперкласса (непосредственного класса-родителя), интерфейсы поддерживают множественное наследование во многих языках программирования. Эта концепция является расширением «простого (или одиночного) наследования» (англ. single inheritance), при котором класс может наследоваться только от одного суперкласса.

В список языков, поддерживающих множественное наследование, входят: Io, Eiffel, C++, Dylan, Python, некоторые реализации классов JavaScript (например, dojo.declare), Perl 6, Curl, Common Lisp (благодаря CLOS), OCaml, Tcl (благодаря Incremental Tcl)[1], а также Object REXX и Dart (за счёт использования классов-примесей).

Множественное наследование позволяет классу перенимать функциональность у множества других классов, как например, класс StudentMusician может наследовать от класса Person, класса Musician и класса Worker, что сокращённо можно написать:

Неопределённость при множественном наследовании, как в примере выше, возникает если, к примеру, класс Musician наследует от классов Person и Worker, а класс Worker, в свою очередь, наследует от Person; подобная ситуация называется ромбовидным наследованием. Таким образом, у нас получаются следующие правила:

Если компилятор просматривает класс StudentMusician, то ему необходимо знать, нужно ли объединять возможности классов или они должны быть раздельными. Например, логично будет присоединить «Age» (возраст) класса Person к классу StudentMusician. Возраст человека не меняется, если вы рассматриваете его как Person (человек), Worker (рабочий) или Musician (музыкант). Однако, будет довольно логичным отделить свойство «Name» (имя) в классах Person и Musician, если они используют сценический псевдоним, отличающийся от настоящего имени. Варианты объединения и разделения вполне корректны для каждого из собственных контекстов и только программист знает, какой вариант является правильным для проектируемого класса.

Smalltalk, C#, Objective-C, Java, Nemerle и PHP не допускают множественного наследования, что позволяет избежать многих неопределенностей. Однако, они, кроме Smalltalk, позволяют классам реализовать множественные интерфейсы. Кроме того, PHP и Ruby позволяют эмулировать множественное наследование за счет использования примесей (traits в PHP и mixins в Ruby), которые, как и интерфейсы, полноценными классами не являются. Множественное наследование интерфейсов позволяет расширить ограниченные возможности.