copal
@copal
𝄞 ...оооо baby

Множественное наследование не нарушает ООП?

Если не брать во внимание какой-либо конкретный язык, а рассуждать в рамках программирования,
то как выглядит множественное наследование в канонах ООП?

Прошу объяснить на своем наболевшем примере - есть класс Node с методами next, prev и есть класс
Task с его execute. Так же есть класс List c inser,Node removeNode.

И вот теперь я хочу получить класс реализующий поведение и Task и Node. Это нормально?
То есть, по сути я хочу реализовать третий класс коллекцию или в моем случаи List, который
будет оперировать нодами-тасками, но до тех пор, пока сам не станет нодой. То есть он для своих
детей будет главным узлом, но в глобальном масштабе будет обычным листом.

Но так как у меня все листы таски, то и сам узел должен быть ещё и таском. Вот как это выглядит
со стороны ООП и со стороны множественного наследования?
В моем случаи это даже не множественное наследование, а множественная реализация интерфейсов
INode, ITask и IList ( IList, это очень сильно сказано, потому что есть ещё один интерфейс, который предоставляет один метод set, в реализации которого происходит вставка переданного объекта в текущий this.next = устанавливаемый метод).

Что скажите?

Для наглядности немного кода...
interface INode {
	next: INode
	prev: INode
}

interface ITask {
	execute(): void;
}

interface ISet {
	insert(target: INode): void;
};

class SomeClass implements INode, ITask, ISet{
	next: INode;
	prev: INode;
	
	execute():void {}
	insert(target: INode):void
	{
		// и здесь просиходит установка таргета
		this.next = target;
		target.prev = this;
	}
}


UPD:1
Спасибо всем за развернутые ответы. Сегодня, продолжая делать вчерашнее, первым что пришло в голову, это строение списка отображения. У языков, которые имеют дисплей лист, есть такие понятия, как parent и child. То есть, если я объект списка отображения и в меня вложены другие объекты списки отображения, то они child. Если меня добавят в точно такой же объект списка отображения, то я стану его чилдом, а так же у меня появится парент. Так же у меня, как у объекта дисплей листа, есть методы для добавления в меня детей.

Этот пример прям мой случай! Только как реализовано хранение детей и парентов?
У меня, как у объекта списка отображения есть лист списка отображения, которым у
меня компазиционные отношения? Или же там тоже next - prew и т.д.?
  • Вопрос задан
  • 957 просмотров
Решения вопроса 4
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
И вот теперь я хочу получить класс реализующий поведение и Task и Node. Это нормально?

Само желание вполне нормально, но лучше все же разделить так как у этих объектов абсолютно разные задачи.

Читаем про SOLID, в частности Принцип подстановки Барбары Лисков. Так же принцип единой ответственности, слабая связанность (low coupling) и высокое зацепление (high cohesion). По поводу реализации нескольких интерфейсов - скажем для композиции двух классов все будет ок, так как вы при этом мы не сломаем принцип единой ответственности, каждый компонент будет отвечать за свое и все будут счастливы. А класс который будет объеденять две реализаци интерфейсов будет просто проксировать вызовы в нужным инстансам.

Множественное наследование норм... только высок риск что все это дело благодаря оному будет нарушено.
Ответ написан
vt4a2h
@vt4a2h
Senior software engineer (C++/Qt/boost)
В вашем случае больше подойдёт агрегация. И, в качестве совета: всегда старайтесь рассматривать агрегацию как альтернативу множественного наследования. Почитайте что-нибудь хорошее по ООП (найдите в сети, есть 100500 ответов на вопрос "что почитать по теме ...").

А каноны ООП -- это нечно мифическое. Есть базовый набор принципов и рекомендаций, а остальное -- опыт и знания. Никогда не будет так как в школе: вот это отлично и так надо делать, а вот это плохо и так делать не надо.

Если очень коротко:
Интерфейс следуют рассматривать как описание набора похожих по смыслу действий, которые можно произвести с экземпляром класса. Например мы можем постучать по всему, реализует интерфейс IKnockable, и в контексте использования данного интерфейса нам не важны остальные характеристики объекта. Постучать, допустим можно по дереву, а можно и по голове.
Понятие наследование от базового класса включает в себя наследование описательных и поведенческих характеристик. Допустим есть класс виджетов, которые умеют себя рисовать, реагировать на команды и прочее. Пусть от виджета наследуется класс MainWindow или класс Dialog. Эти классы умеют себя рисовать как и виджет, имеют свойства прозрачности (допустим) и прочие, однако содержат что-то новое элементы управления по умолчанию, предопределённые свойства модальности иное поведение и пр.
Конечно неплохо было бы учесть некоторые принципы SOLID, но вопрос не про это...
Ответ написан
@bromzh
Drugs-driven development
Не нарушает, так как до сих пор нет единого мнения, что такое ООП и какая из его реализаций самая правильная. Даже те 4 принципа, про которые все любят говорить (инкапсуляция, наследование, полиформизм, абстракция) не являются ни исключительными для ООП (так как встречаются в любых других языках), ни необходимым набором правил, которым должен удовлетворять ОО язык, так как многие языки хоть и являются ОО, но в них могут отсутствовать наследование (прототипное ООП) и инкапсуляция в явном виде (для сокрытия внутренностей тогда используют замыкания или вообще не парятся). Полиформизм и абстракция присущи вообще всем языкам.

Просто надо понимать, где стоит использовать множественное наследование в том или ином его варианте, где оно излишне, а где вообще не нужны объекты и классы.
Ответ написан
halogen
@halogen
Java developer
Не нарушает, так как не является составляющей, которая определяет "правила" ООП. Под множественным наследованием, привносящим проблемы, скорее следует понимать наследование классов, то есть, готового поведения и состояния. С наследованием интерфейсов проблемы как таковой на уровне реализации интерфейсов нет, но может в некоторых случаях быть неприятной в JVM-языках, когда реализуемые интерфейсы декларируют методы с одинаковыми именами, но методы семантически разные. Это чисто техническая проблема. В то же время, в среде .NET, насколько я помню, этой проблемы нет. Класс, реализующий несколько интерфейсов -- вполне обычная и хорошо зарекомендовавшая себя практика (например, стандартная библиотека виджетов GWT; "наблюдаемые" коллекции в .NET и пр.)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@FoxInSox
Реализация нескольких интерфейсоф - ок.
Множественное наследование - не ок.

Правда, все относительно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы