Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.29;
Скачать: CL | DM;

Вниз

Вот спорю с коллегой на работе, подскажите есть ли множественное   Найти похожие ветки 

 
Гаврила ©   (2004-08-10 12:31) [40]


> Игорь Шевченко ©   (10.08.04 12:21) [37]


Создать class1 надо конечно, поскольку он является полем class2, то и создать его логично в конструкторе class2. Вот и весь код. НУ а передавать ли ему ссылку на class1 - от задачи зависит :-)


 
Игорь Шевченко ©   (2004-08-10 12:33) [41]

Romkin ©   (10.08.04 12:24) [38]


> А если еще учесть, что при использовании интерфейсов есть
> возможность агрегировать в себя (читай - унаследовать) всю
> функциональность класса, написанного на другом языке, то
> становиться понятным, почему я говорю, что множественное
> наследование классов устарело :))


Множественность-то здесь причем ? Вся эта фраза точно также относится и к одиночному наследованию.


> А при использовании интерфейсов таких тонкостей просто нет.
> И более того, с интерфейсами для того, чтобы твой класс
> воспринимался как предок, ты не обязан порождать свой класс
> от предка, можно просто реализовать его интерфейс. Так,
> как хочется.


Дублируя код предка, если требуется его функциональность ? :))


> Простой пример: у предка есть виртуальный метод, наследник
> его перекрывает, но не вызывает в нем inherited, собственно
> метод предка. Допустимо ли это технологией? Конечно. Но
> ведь потомок не знает, что делает метод предка, который
> он не вызвал. А он может делать что-то, затрагивающее функциональность
> предка, да хоть количество его вызовов подсчитывать :) Вот
> и получается, что программист, написав потомок, вторгся
> в логику работы предка, и изменил ее!


Опять же, причем тут именно множественное наследование ? Все это точно так же может быть отнесено к одиночному наследованию, однако его, почему-то ничкто не отменяет и не пишет, что оно устарело :))


 
Игорь Шевченко ©   (2004-08-10 12:34) [42]

Romkin ©   (10.08.04 12:30) [39]


> Создавать придется. Но перенаправлять ничего не надо, все,
> что нужно агрегату, это IUnknown class2. А это предусмотрено,
> см CoCreateInstance, параметр pUnkOuter


Я вообще-то не про COM...Я вообще-то про обычное использование интерфейсов и наследование...Я в COM не так силен, как ты :)


 
DiamondShark ©   (2004-08-10 12:35) [43]

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


 
Игорь Шевченко ©   (2004-08-10 12:36) [44]

Гаврила ©   (10.08.04 12:31) [40]


> Создать class1 надо конечно, поскольку он является полем
> class2, то и создать его логично в конструкторе class2.
> Вот и весь код. НУ а передавать ли ему ссылку на class1
> - от задачи зависит :-)


Только вот я не совсем понимаю, чем это лучше, чем множественное наследование ? :)


 
Гаврила ©   (2004-08-10 12:39) [45]


> Игорь Шевченко ©   (10.08.04 12:36) [44]


Да это и не лучше, просто нет его, множественного наследования у нас :-)


 
Romkin ©   (2004-08-10 12:40) [46]

Игорь Шевченко ©  (10.08.04 12:33) [41] При том, что оно становиться не нужным :)))
А одиночное - можно обойтись и без него, но оно удобно. А главное - достаточно.
>Дублируя код предка, если требуется его функциональность ? :))
Вот именно. Ты можешь унаследовать предка, можешь его агрегировать, а можешь продублировать его фукнциональность :)
На выбор. И при этом пользователь твоего потомка просто не догадается, как именно ты сделал :)))
Более того, пользователь часто вообще не знает, как и где именно реализован данный интерфейс ;)


 
Игорь Шевченко ©   (2004-08-10 13:08) [47]

DiamondShark ©   (10.08.04 12:35) [43]


> Наследование -- инструмент повторного использования кода.


Игорь Шевченко ©   (10.08.04 10:09) [10]


> Мне, например, из-за его отсутствия приходится писать лишний  > код. Иногда напрягает


:)

Romkin ©   (10.08.04 12:40) [46]

> А одиночное - можно обойтись и без него, но оно удобно.
> А главное - достаточно.


Честно говоря, не понимаю :)


> Вот именно. Ты можешь унаследовать предка, можешь его агрегировать,
> а можешь продублировать его фукнциональность :)


Собственно говоря, введение множественного наследования не мешает мне сделать те же три действия :)


> Более того, пользователь часто вообще не знает, как и где
> именно реализован данный интерфейс


Какой пользователь имеется в виду ?


 
Антон   (2004-08-10 13:16) [48]

Я вообще-то в Delphi не секу, пишу на С++, а этот форум зинтересовал меня по простой причине, хочу понять, есть ли объективые причины почему в Delphi не реализовано множественное наследование. Я исключаю ответы типа устарело, излишне, приводит к ошибкам. Основной вопрос - может ли это быть связано с различием в процессах распеделения памяти и т.п.

А вообще множественное наследование легко реализуется простым вложением двух объектов различных классов в качестве членов третьего, далее остается только предоставить код, возвращающий адреса этих объетов. Так например:


class A { };
class B { };

class C : public A, public B { };
экивалентно
class C { A a; B b; }



 
Игорь Шевченко ©   (2004-08-10 13:22) [49]


> А вообще множественное наследование легко реализуется простым
> вложением двух объектов различных классов в качестве членов
> третьего, далее остается только предоставить код, возвращающий
> адреса этих объетов. Так например:
>
>
> class A { };
> class B { };
>
> class C : public A, public B { };
> экивалентно
> class C { A a; B b; }


Не эквивалентно. Класс C не может быть представлен ни как класс A, ни как класс B


 
Антон   (2004-08-10 13:29) [50]

Хорошо, продолжу:

struct A {};
struct B {};
struct C {
  A a; B b;
  operator A* () { return &a; }
  operator B* () { return &b; }
};

void f()
{
  C c;
  A* p_a = c;
  B* p_b = c;
  cout << p_a << " " << p_b << " " << &c << endl;
}

В результате видим примерно следующее:
0012FF74 0012FF78 0012FF74
Это аблолютная аналогия.


 
Игорь Шевченко ©   (2004-08-10 13:46) [51]


> В результате видим примерно следующее:
> 0012FF74 0012FF78 0012FF74
> Это аблолютная аналогия.


???????????????????? Эт как ?


 
Piter ©   (2004-08-10 13:57) [52]

Игорь Шевченко ©   (10.08.04 10:09) [10]
Мне, например, из-за его отсутствия приходится писать лишний код. Иногда напрягает


а можно пример, когда множественное наследование полезно?


 
Антон   (2004-08-10 13:58) [53]

> ???????????????????? Эт как ?
Аналогичный результат я получу если просто напишу класс С при помощи синтаксиса множественного наследования, как показывал выше. Дело в том, что память распределится идентичным образом в обоих случаяю, поэтому разницы никакой нет.


 
Антон   (2004-08-10 14:02) [54]

> а можно пример, когда множественное наследование полезно?

Есть такой мультик - КОТОПЕС, а если серъезно, то любое моделирование гибридных объектов.


 
Piter ©   (2004-08-10 14:46) [55]

Антон   (10.08.04 14:02) [54]

нет, мне бы пример. Например, постановка задачи и путь ее реализации. Желательно в терминах Delphi

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


 
DiamondShark ©   (2004-08-10 14:51) [56]


> то любое моделирование гибридных объектов.

Агрегирование.


 
Игорь Шевченко ©   (2004-08-10 14:59) [57]


> Аналогичный результат я получу если просто напишу класс
> С при помощи синтаксиса множественного наследования, как
> показывал выше. Дело в том, что память распределится идентичным
> образом в обоих случаяю, поэтому разницы никакой нет.


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


 
Антон   (2004-08-10 15:43) [58]


> Это зависит от конкретной реализации языка, не так ли ?
> Синтаксис наследования является стандартом языка, в то время,
> как распределение памяти стандартом отнюдь не является.

Вот это меня и интерисует, я как абсолютный профан в Delphi, не знаю можно ли аналогично реализовать множественное наследование посредством агрегации, как я показал на примере с С++. Это был пример для обсуждения и не больше. Что мешает реализовать аналогично множественное наследование в Delphi, вот в чем вопрос? Ведь у вас есть простое наследование, нет операторов преобразования типа как в С++, но их можно заменить и на обычные ф-ии члены класса (воспрос синтаксиса)?


 
Антон   (2004-08-10 15:50) [59]


> нет, мне бы пример. Например, постановка задачи и путь ее
> реализации. Желательно в терминах Delphi
>
> Например, нечто реализовывается так. Но вот если было бы
> множественное наследование - то это можно было бы реализовать
> гораздо проще, потому что...

Прости, в терминах Delphi не могу, просто не знаю, да и дело не в терминах. Я могу привести пример реализации библиотеки Motif. Она не относится к вопросу о множественном наследовании. Но она эмулирует C++ в части скрытия данных и разграничения доступа, хотя это чисто С библиотека. Можно использовать средства языка для эмуляции средств не реализованных в языке, но проще пользоваться синтаксисом заложенным изначально в язык, по моему это удобнее.


 
Игорь Шевченко ©   (2004-08-10 15:51) [60]


> Вот это меня и интерисует, я как абсолютный профан в Delphi,
> не знаю можно ли аналогично реализовать множественное наследование
> посредством агрегации, как я показал на примере с С++.


Я имел в виду, что в различных реализациях одного языка (С++) реализация может быть разная.


 
Антон   (2004-08-10 16:09) [61]


> Я имел в виду, что в различных реализациях одного языка
> (С++) реализация может быть разная.

Понял твой намек. Дело в том что модесь COM, которая упоминалась в форуме реализуется именно с помощью агрегации, спорить с этим бесполезно. Так на чем же она основывается? Ответ очевиден. Что-бы предоставить доступ к интерфейсу, не использую конструкции C++, приходится эмулировать его с помощью агрегации...


 
Mystic ©   (2004-08-10 16:18) [62]

Вот пример. Есть библиотека где представлены различные классы (со своей иерархией наследования), в том чсле TSomeClass. Допустим, эту библиотеку мы изменять не можем. В определенный момент равития системы (пишется компонет, имеюший published свойство типа TSomeClass). Нам надо чтобы этот класс был порожден от TPersistent и умел сохраняться в поток, присваиваться и т. д.


 
Антон   (2004-08-10 16:28) [63]


> Я имел в виду, что в различных реализациях одного языка
> (С++) реализация может быть разная.

Я думаю, ты понял, что проблема не в реализации компилятора, а в том, что компилятор для Object Pascal невозможно реализовать аналогично, что именно мешает мне и интересно, возможны варианты, один из которых - однопроходность, но это только для затравки...


 
Игорь Шевченко ©   (2004-08-10 16:30) [64]


> Я думаю, ты понял, что проблема не в реализации компилятора,
> а в том, что компилятор для Object Pascal невозможно реализовать
> аналогично, что именно мешает мне и интересно, возможны
> варианты, один из которых - однопроходность


Однопроходность здесь ни с какого боку, вроде...

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


 
Cobalt ©   (2004-08-10 16:49) [65]

2 Mystic ©   (10.08.04 16:18) [62]
Минуточку - тут имеет место небольшое лукавство:
Если это компонент (для формы/ДатаМодуля) - он уже наследуется от TPersistent - и это упрощает дело
Если же это просто класс - то это уже не проблема вызвать у него метод SaveToStream самому (на мой взгляд).


 
Игорь Шевченко ©   (2004-08-10 17:02) [66]


> Если же это просто класс - то это уже не проблема вызвать
> у него метод SaveToStream самому (на мой взгляд).


А если его нету ?


 
Антон   (2004-08-10 17:17) [67]


> > Если же это просто класс - то это уже не проблема вызвать
> > у него метод SaveToStream самому (на мой взгляд).
> А если его нету ?

Причем метод которого нету, можно конечно реализовывать "ЖИРНЫЙ" интерфейс, который предусматривает чисто фиртуальные метомы (в вашем понимании интерфейсы), обеспечивая совместимость на уровне вызова ф-ий членов, но для чего? Елсли нет возможности преобразовать тип во время исполнения в производный, только тогда возможен изврат с ЖИНЫМ интерфейсом (а как на счет производных классов которые в приципе не могут реализовать данный интерфейс..., что делать заглушки...?)


 
Cobalt ©   (2004-08-10 17:52) [68]

Хм..
Есть класс (TParent1), который изменять нельзя. Порождён не от TMyClass1.
Надо: Добавить ему функционал этого TParent2.

 Решение 1: Без использования множественного наследования
Добавляем в новый класс(TChild) поле типа TParent2. Устанавливаем его свойства, обработчики и т.п. Везде, где надо, суём поле, а не сам класс (TChild).
+ Хорошо, если этот функционал не должен затрагивать функционал и поля TParent1.
- Плохо, если необходимо чтобы новый функционал работал с полями исходного класса TParent1 как со своими собственными

 Решение 2: С использованием множественного наследования
Добавляем в новый класс(TChild) родителя типа TParent2. У него появляются новые поля и методы для исполнения соответствующего функционала.

Вопрос - как TParent2 должен взаимодействовать с Методами и Полями другого TParent1 в TChild?


 
Cobalt ©   (2004-08-10 17:53) [69]

Я как-то пока себе не представляю.


 
Cobalt ©   (2004-08-10 18:08) [70]

Ещё - если функционал TParent2 должен работать с полями TParent1, то в TChild надо переписывать эти методы.

Выигрыш - TChild на вопрос is TParent1 ответит True, и позволит работать с классом, как с TParent1.

P.S.
Cobalt ©   (10.08.04 17:52) [68]
Следует читать:
Есть класс (TParent1), который изменять нельзя. Порождён не от TParent2.
Надо: Добавить ему функционал этого TParent2.


 
Romkin ©   (2004-08-10 18:13) [71]

Бррр. Ну что вы маетесь?! Я вообще уже ничего не понимаю.
В Delphi нет множественного наследования классов. Оно не обязательно.
Но если очень хочется - есть множественное наследование интерфейсов, и пользоваться им гораздо приятнее :)
Например, можно создать потомка на Delphi от класса, написанного на С++ Ж-)


 
Cobalt ©   (2004-08-10 18:26) [72]

просто меня тоже заинтересовало - были ли какие-то объективные причины для того, что бы не реализовывать множественное наследование в Delphi? Или просто решили, мол, нафиг это не надо, не будем с этим заморачиваться, и вообще это непопулярно, и забили на этом жирный крест.


 
Romkin ©   (2004-08-10 18:35) [73]

Естественно, просто решили.
Надо будет - введут. Но лучше не надо :)


 
Cobalt ©   (2004-08-10 19:49) [74]

Отчего же?
Довольно-таки удобно, компилятор будет ругаться на вызов метода без указания его родителя (при наличии нескольких одноимённых у разных предков), все будут довольны :)


 
Бином Ньютоныч   (2004-08-10 19:54) [75]

Причины, имхо, вполне конкретые. Множ. наследование - бред бушевноболдьного. Два - три этапа - и в эторм классе сам черт со страуртруппом не разберутся, не говоря уж про нас, бедных...:(


 
Бином Ньютоныч   (2004-08-10 19:57) [76]

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


 
Cobalt ©   (2004-08-10 20:56) [77]

2 Бином Ньютоныч   (10.08.04 19:54) [75]
Ну, не скажите. Если программист запутался втом, что же делает  (может делать) его класс - это его проблема. при строгом непересекающемся наследовании я не вижу проблем составить карту методов и полей, унаследованных от всех его родителей.

Единственная проблема, которую я углядел - конфликт Published-свойств у компонентов - как их отображать? сохранить в dfm?
Загружать из dfm? Вот это, кажется - самое трудное - пришлось бы, наверное, добавлять в RTTI данные о классах и их Published-свойствах - для того, что бы можно было выбирать. Типа
GetParentClass(Parent1Name).SetProperty(PropertyName1).AsString

P.S. Я пробовал смотреть исходники TReader, но, честно говоря, не понял - где же он устанавливает значение Published-свойств?


 
Бином Ньютоныч   (2004-08-10 21:32) [78]

>Cobalt ©   (10.08.04 20:56) [77]

Извините, но большая часть Вашей работы - это использование чуого кода(VCL) И это здорово, я не против:)

Да нет, Вы просто попробуйте построить иерархию со множественным наследованием. Ничего сложного не используйте, все обыденно: источник данных, обраьотчик коллизий, интерфейс юзера... Потом сделайте еще шаг - администратор. Потом Вам(юзеру) захочется быть супервизором. А кому не хочется - всем хочется. Но мы не позволим, мы умные, видали уже. Однако заказчик настаивает. Ладно, Вы обговорили бабки, но слабина уже есть! Он захочет большего, причем в рамках. Откажешь? Дудки, это же клиент, деньги, жизнь... А дальше? Ну сколько ты будещь расширять функ. в рамках языка? А когда выйдет за рамки?  Но это все хрень. Что мне ДЕЙСТВИТЕЛЬНО непонятно - как ты будешь обеспечивать БЕЗОПАСНОСТЬ всей этой хрени? Поделись:)


 
Cobalt ©   (2004-08-10 21:47) [79]

Я чувствую, ты что-то хочешь сказать мне, что-то наболевшее...
Но вот что - я никак не пойму.


 
Cobalt ©   (2004-08-11 17:37) [80]

Может, ещё какие есть объективные причины для отсутствия множественного наследования?



Страницы: 1 2 вся ветка

Текущий архив: 2004.08.29;
Скачать: CL | DM;

Наверх




Память: 0.66 MB
Время: 0.027 c
4-1088846360
Sj
2004-07-03 13:19
2004.08.29
TaskBar + System Tray в Delphi


3-1091519205
Labert
2004-08-03 11:46
2004.08.29
OCI, Parse, Prepare, курсоры и т.п.


3-1091592599
ydv
2004-08-04 08:09
2004.08.29
Хитрый sql-запрос


14-1092297754
Holy
2004-08-12 12:02
2004.08.29
Оригинальный приезд


3-1091608608
dtm
2004-08-04 12:36
2004.08.29
Европейские языки в базе данных.