?

Log in

No account? Create an account
Множественное наследование - In 3.14 we trust [entries|archive|friends|userinfo]
BrotherFlame

[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Множественное наследование [Mar. 9th, 2010|02:27 pm]
BrotherFlame
Столкнулся с тем, что некоторые относят невозможность множественного наследования к минусам Java. Утверждение сомнительно, но еще хуже чудовищно неправильный пример, который один раз привели: 
Ребенок наследует признаки и поведение обоих родителей.
class Father extends Human {...}
class Mother extends Human {...}
class Child extends Mother, Father
Что с точки зрения здравого смысла ерунда полная.
Потому что потерян смысл различий агрегации и наследования.
Адекватней было бы написать:
class Child extends Human {
      Human Father;
      Human Mother;
}

Попытался придумать пример, когда тяжело обойтись без множественного наследования.
Ну типа, комп -- это и товар, и электронное устройство... Но ничего осмысленного придумать не смог.

Какие объекты реального мира можно описать, используя множественное C++ наследование?
LinkReply

Comments:
From: (Anonymous)
2010-03-09 08:02 pm (UTC)

Юджин

Класс с хьюманами ты не совсем верно спроектировал. А если подумать?

CHuman - базовый класс, который может вобрать в себя такие свойства, как возраст, цвет глаз, масса мозга и т.п. CMother и CFather и мы исправляем на CWomen и СMan, так ведь? Эти классы наследуют CHuman и каждый добавляет еще свойства: такие как размер гениталий (кстати, размер груди можно включить в CHuman :), остальные параметры :) - только в производные классы). Далее, вот есть хьюман - сам по себе он появиться на свет не может - должны быть мама с папой :) И вот именно с этого момента и появляются твои Mother, Father, но они - не классы, они экземпляры классов. Ссылки (или указатели на них) следует передать через конструктор. Согласен? Мама с папой - это экземпляры классов с CWoman и CMen. определяем пол ребенка и в зависимости от этого создаем экземпляр класса. Вот так выглядит конструктор на примере малыша мужского пола CHuman* pMan = new CMen( pFather, pMother );

Когда малыш станет взрослым и все необходимые размеры станут заметными, а вес мозга достигнет весомого состояния, он встретить CHuman* pWoman и у них появится, CHuman* pChild = new CWomen( pMan, pWoman );

Эх ты! :))) А ты чё понаписал??? Мама с папой - члены класса??!!! Указатели надо хранить! Тогда можно построить целое генеологическое древо. От самого Бога (у которого мама с папой равны NULL). Более того, не забывай - ребенка могут усыновить две девушки :) Шура, надо принимать во внимание все аспекты, проектируя код :)))

(Reply) (Thread)
[User Picture]From: brotherflame
2010-03-09 08:52 pm (UTC)

Re: Юджин

Жень, я синтаксически правильно написал с т.з Явы. Там нет понятия указатели, значения и ссылки -- там все через ссылки. Кроме примитивных типов. Остальное -- ссылки. И в методы везде передаются ссылки, а не сами объекты. Это основное отличие от С++. Но к проектированию иерархии лассов это не относится.

Так погоди, я не понял, в каком случае нам может понадобиться множественное наследование?
(Reply) (Parent) (Thread)
[User Picture]From: brotherflame
2010-03-09 09:08 pm (UTC)

Re: Юджин

Да тут если дерево строить конечно нужно по-другому писать.
Но то пример не на множественное наследование, а на рекурсию больше.
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-03-10 04:18 am (UTC)

Юджин

Синтаксически верно, алгоритмически - нет. Тогда используй ссылки.

Шур, вот у тебя задача - сделать двусвязанный список на Java. Ты как свяжешь элементы?
(Reply) (Parent) (Thread)
[User Picture]From: brotherflame
2010-03-10 06:35 am (UTC)

Re: Юджин

вообще меня интересовал пример на множественное наследование. Но если уж так, то в данном случае двусвязный список -- это неверное решение.
Правильное -- дерево.
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-03-10 08:30 am (UTC)

Юджин

Шур, двухсвязанный список - это к вопросу, как бы ты его сделал, ипользуя Яву.

То, что в хьюманах дерево - это очевидно.
(Reply) (Parent) (Thread)
[User Picture]From: brotherflame
2010-03-10 08:34 am (UTC)

Re: Юджин

Не, я бы взял TreeSet, а не LinkedList
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-03-10 08:58 am (UTC)

Юджин

Блин, да ты о чем пишешь. Двухсвязвнный список - это к вопросу ссылок на объекты, где объекты - элементы списка, к хьюманам никакого отношения не имеет.

Теперь к хьюманам: мы решали задачу в контексте наследования (!!!), причем тут TreeSet???
(Reply) (Parent) (Thread)
[User Picture]From: brotherflame
2010-03-10 08:59 am (UTC)

Re: Юджин

Дерево потому что, и нет одинаковых элементов.
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-03-09 08:23 pm (UTC)

Юджин

А теперь серьезно. Комп - это товар и электронное устройство = не свосем подходит под множественное наследование. Электронное устройство, скорее тип товара, нежели наследование функционала. Шура, наследование функционала! Объект из реального мира описать сложно. Полагаю, всегда можно постараться запихнуть второй наследуемый класс в первый наследуемый. Типа, "...ну и пусть он тоже включает в себя эти свойства...". Но в программировании это не всегда так. Множественное наследование - это наследование разнородным базовым классам, добавляя все новый функционал в производный. Более того, смысл интерфейсного программирования основывается на множественном наследовании. Открой книгу Дейла Роджерсона, которую ты мне так и не отдал, зараза :))) уже 5 лет прошло :))) Почитай, там много интересных вещей.

А аргегирование никак не связано со множественным наследованием. Смысл агрегирования - использовать готовый функционал, не включая реализацию. Не знаю, может в Яве не так.
(Reply) (Thread)
[User Picture]From: brotherflame
2010-03-09 08:55 pm (UTC)

Re: Юджин

Не, ООП от языка не зависит.
В яве я могу расширить функционал через интерфейсы, которых класс может реализовать сколько угодно. Но то будут реализации методов. А полей у интерфейсов нет (кроме статических).
Пытался придумать конкретный пример, для реального множественного наследования, когда нужно именно не только функционал расширить, а расширить само понимание сущности, и не смог придумать.
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-03-10 04:33 am (UTC)

Юджин

Шур, ты уже ответил на свой вопрос. Объяви класс с несколькими интерфейсами. Что получилось? Правильно - множественное наследование.

public class CA extends CB implements CI { }

Или ты думаешь, это НЕ множественное наследование??? CI - это интерфейс без реализации. И что?
(Reply) (Parent) (Thread)
[User Picture]From: brotherflame
2010-03-10 06:37 am (UTC)

Re: Юджин

Короче, те кто пишут про отсутствие множественного наследования в Java просто слабо понимают ООП. ИМХО, через интерфейсы -- это полноценное множественное наследование в котором убрано лишнее: множественное наследование полей.
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-03-10 08:50 am (UTC)

Юджин

Да причем тут наследование полей? Наследуются не только члены класса, но и реализации.

есть класс CWindow, который реализует обычное окно. Есть три объекта:
кнопка, фрейм, представление и popup-окно (типа меню).

class CButton : CWindow;
class CFrame: CWindow;
class CView : CWindow;
class CPopup : CWindow;

Известно, что фрейм "умеет" изменять свои размеры и сохранять их например в файл настроек. Скажем, CPopup - тоже, а что такого? Пусть умеет. CButton - не умеет, она автоматически рендерится по размер текста. CView - тоже не умеет, оно растягивается по размерам фрейма.
Теперь CPopup и CView могут скроллировать свое содержимое. Фрейм и кнопка - не могут.

Теперь я ввожу еще два класса, реализации которых я буду повторно использовать: CSaveWindowPos, CScrollContent;

Теперь давай распишем как будут выглядеть наши классы:

class CButton : CWindow;
class CFrame : CWindow, CSaveWindowPos
class CView : CWindow, CScrollContent;
class CPopup : CSaveWindowPos, CScrollContent;

Попробуй исключи множественное наследование. Что у тебя получится?
Придется делать все комбинации базовых классов. А зачем? Вспомогательных классов может быть очень много. Что, все комбинации делать.

Наследование интерфейсов не является полноценным множественным наследованием.
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-03-10 08:53 am (UTC)

Юджин

В объявлении CPopup забыл CWindow :)
(Reply) (Parent) (Thread)
[User Picture]From: brotherflame
2010-03-10 08:56 am (UTC)

Re: Юджин

Без всякого ущерба для красоты ООП лечится шаблоном Декоратор.

(Reply) (Parent) (Thread)
From: (Anonymous)
2010-03-10 09:13 am (UTC)

Юджин

Несовсем. Декоратор - это включение. Ты обязан сделать врапперы методов для того, чтобы вызвать метод компонента, расширяющего функциональность.

Шур в разных случаях - я использую разные подходы. И множественное наследование так же использую.
(Reply) (Parent) (Thread)
[User Picture]From: brotherflame
2010-03-10 08:59 am (UTC)

Re: Юджин

Либо для скролинга можем добавлять элементы в ScrollPane
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-03-10 09:17 am (UTC)

Юджин

Опять ты про конечные классы. Схема с классами - условная. Подобных ситуаций я встречаю очень много.
(Reply) (Parent) (Thread)
[User Picture]From: brotherflame
2010-03-09 09:10 pm (UTC)

Re: Юджин

Легким движением руки класс превращается, класс превращается, превращается!
В Адаптер. Но одно из свойств адаптара в том, что в нормально проектиуемом изначально коде, адаптер появиться не должен.
(Reply) (Parent) (Thread)