C ++ имеет простое множественное наследование, многие языковые схемы запрещают его как опасное. Но некоторые языки, такие как Ruby и PHP, используют странный синтаксис, чтобы делать то же самое и называть это миксинами или чертами. Я много раз слышал, что миксином / признаками сложнее злоупотреблять, чем простым множественным наследованием.
Что конкретно делает их менее опасными? Есть ли что-то, что невозможно с миксином / признаком, но возможно с множественным наследованием в стиле C ++? Можно ли столкнуться с проблемой алмазов с ними?
Это выглядит так, как будто мы использовали множественное наследование, но просто оправдываемся тем, что это миксины / черты, чтобы мы могли их использовать.
Ответы:
Существует несколько проблем с множественным наследованием, когда оно используется с полноценными классами, но все они вращаются вокруг неоднозначности .
Неоднозначность проявляется несколькими способами:
x
и тем же полем и запрашивается производный типx
, что он получает?x
переменные имеют несовпадающие типы, вы можете сделать это.f
с одинаковыми сигнатурами, и кто-то вызываетf
, что вызывается ?И это игнорирует такие вещи, как динамическая диспетчеризация, вывод типов, сопоставление с образцом и другие вещи, о которых я знаю меньше, которые становятся более сложными, когда язык поддерживает множественное наследование полных классов.
Черты или Mix-In (или интерфейсы, или ...) - это все конструкции, которые специально ограничивают возможности типа, так что нет никакой двусмысленности. Они редко владеют чем-либо самим. Это позволяет сгладить состав типов, потому что нет двух переменных или двух функций ... есть переменная и ссылка; функция и подпись. Компилятор знает, что делать.
Другой распространенный подход - заставить пользователя «встраивать» (или смешивать) свой тип по одному. Вместо того, чтобы базовые классы были равноправными партнерами в новом типе, вы добавляете один тип к другому, переопределяя все, что там было (обычно с необязательным синтаксисом для переименования и / или повторного раскрытия переопределенных битов).
В зависимости от языка - обычно становится проблематичным или невозможным объединять реализации функций и хранилище для переменных из нескольких базовых классов и представлять их в производном типе.
Иногда появляются менее серьезные изменения в зависимости от вашего языка, но обычно нет. Весь смысл черт состоит в том, чтобы сломать такую двусмысленность.
источник
with
делает ключевое слово.