Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.156] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 155 156 [157] 158 159 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#2341
,
|
|
|
|
Цитата D_KEY @ Так обсуждается вопрос о том, является ли два метода, обладающие одинаковым именем и имеющие одинаковую сигнатуру, из разных "интерфейсов" одним и тем же методом. Я не понимаю, почему в статике(шаблоны и концепты) должно быть одно поведение(один метод), а в динамике(интерфейсы) должно быть другое(два метода и конфликт)? Напомню, что речь не об абстрактных классах и множественном наследовании. Так ведь и в статике тоже будет конфликт, если вдруг каким-то образом у MyObj окажется два метода "void mf() const". |
|
Сообщ.
#2342
,
|
|
|
|
Цитата Adil @ Цитата D_KEY @ Так обсуждается вопрос о том, является ли два метода, обладающие одинаковым именем и имеющие одинаковую сигнатуру, из разных "интерфейсов" одним и тем же методом. Я не понимаю, почему в статике(шаблоны и концепты) должно быть одно поведение(один метод), а в динамике(интерфейсы) должно быть другое(два метода и конфликт)? Напомню, что речь не об абстрактных классах и множественном наследовании. Так ведь и в статике тоже будет конфликт, если вдруг каким-то образом у MyObj окажется два метода "void mf() const". А каким образом это будет возможно? Да и в случае интерфейса тоже не понятно, как это может быть? Ведь класс не наследует от интерфейса, а реализует интерфейс. |
|
Сообщ.
#2343
,
|
|
|
|
Не, вот прямо сейчас качнул драфт Цитата 13.5/3 The following operators cannot be overloaded: . .* :: ?: Добавлено Цитата D_KEY @ А каким образом это будет возможно? Ну, стоит только наследовать от двух классов, в каждом из которых есть void mf() const - и уже придётся разруливать в статике. Добавлено Что-то я туплю... В списке разрешённых к перегрузке присутствует ->* |
|
Сообщ.
#2344
,
|
|
|
|
Цитата Qraizer @ Тут всё открыто, поэтому достать элементы отдельно от контейнера не составляет труда. задача была сделать доставание объекта невозможным |
|
Сообщ.
#2345
,
|
|
|
|
Цитата MyNameIsIgor @ Цитата D_KEY @ А каким образом это будет возможно? Ну, стоит только наследовать от двух классов, в каждом из которых есть void mf() const - и уже придётся разруливать в статике. Но это уже разруливание проблемы множественного наследования, а не интерфейсов. |
|
Сообщ.
#2346
,
|
|
|
|
Цитата D_KEY @ Но это уже разруливание проблемы множественного наследования, а не интерфейсов. И что? Метода то всё равно два. Какая разница? И потом, а что ты предлагаешь? Чтобы два одинаковых по сигнатуре и названию метода двух разных интерфейсов сливались в один? И если я реализую сразу два интерфейса, например, из разных библиотек, у которых методы совпадут, я должен один написать? Несмотря на то, что это вообще то разные методы? Не, это фигня. |
|
Сообщ.
#2347
,
|
|
|
|
Цитата MyNameIsIgor @ Чтобы два одинаковых по сигнатуре и названию метода двух разных интерфейсов сливались в один? Они не могут сливаться или не сливаться. Неверная постановка вопроса. ИМХО Ты не наследуешь от этих интерфейсов. Ты говоришь: "я реализую эти интерфейсы". То есть методов еще нет - ты их только создаешь. Так что и сливать тебе еще нечего. Цитата И если я реализую сразу два интерфейса, например, из разных библиотек, у которых методы совпадут, я должен один написать? Не должен, а можешь. Вернее это поведение по умолчанию, но ты можешь сказать, что метод вот этого интерфейса ты реализуешь так, а метод другого - так. В случае множественного наследования классов(и обычных и абстрактных) - да, должен быть конфликт по умолчанию. Цитата Несмотря на то, что это вообще то разные методы? А что их отличает друг от друга? |
|
Сообщ.
#2348
,
|
|
|
|
Цитата D_KEY @ Ты не наследуешь от этих интерфейсов. Ты говоришь: "я реализую эти интерфейсы". Как будто я это не понимаю ![]() Цитата D_KEY @ То есть методов еще нет - ты их только создаешь. Так что и сливать тебе еще нечего. Но они должны быть - интерфейсы требуют. Вопрос в том, разные это будут методы или нет. Цитата D_KEY @ Не должен, а можешь. Вернее это поведение по умолчанию Это очень странное поведение. В адрес подобного дизайна языка я могу сказать лишь маты ![]() Цитата D_KEY @ А что их отличает друг от друга? Эти методы принадлежат разным интерфейсам. Ну, или если мы говорим исключительно с точки зрения теории то разные интерфейсы требуют реализации этих методов. |
|
Сообщ.
#2349
,
|
|
|
|
Цитата Qraizer @ Только высказывания бредовые, мол, "одноимённые методы разных интерфейсов обязаны стать один и тем же методом, а если нет, то либо авторы интерфейсов индусы, либо я индус". А в чём заключается бредовость? Вот совершенно рядовая ситуация, когда у интерфесов есть общая реализация - разделение прав доступа, гипотетические интерфейсы IReadOnly - только для чтения и IAllAccess - для полного доступа. Иначе, если общая реализация не требуется - ты разруливаешь коллизию. Цитата Qraizer @ Давай не надо. Плюсы имеют то же поведение. Ты как обычно либо не дочитал того, на что я дважды обратил внимание, либо не понял и постеснялся спросить. Знаешь, вот глядя на твою абсолютную "непробиваемость" - меня не покидает стойкое чувство, что ты где-то что-то вычитал о интерфейсах, но скорей всего неправильно это трактовал... Если ты конечно не о Цитата Qraizer @ Я о логике компилятора. Видишь ли, контракт интерфейсы как раз и описывают. Мне кажется гораздо более разумным по дефолту кричать о неоднозначности, если компилятор увидит методы с одинаковыми сигнатурами в более чем одном интерфейсе, как раз потому, что раз интерфейсы независимы, то и контракты у них разные. А коли так, то класс, реализующий оба интерфейса, должен выдерживать оба контракта, и единый метод одновременно для всех коллизируемых - это редкая ситуация. банальном отсутствии Warning'а. Ну а я разжувал: Цитата DesweR @ Это отчасти вытекает из идеологии COM'а, интерфейс - это абстрактный протокол, который описывает только взаимодействие с объектом и не содержит детали его реализации. Возьмём класс X, реализующий некоторый функционал, класс X могут наследовать несколько других классов XA, XB, XC, в этом случае они наследуют и расширяют функционал родительского класса X, но никак его не замещают и не ограничивают, работает принцип подстановки Лисков, мы можем создать объект любого из дочерних классов, привести его к базовому и спокойно работать. Теперь возьмём интерфейс Y, описывающий некоторый абстрактный протокол, этот интерфейс могут реализовывать несколько классов YA, YB, YC, в этом случае они "наследуют" и реализовывают протокол взаимодействия и т.к. никакой базовой реализации у интерфейса нет - YA, YB, YC реализовывают протокол взаимодействия полностью сами, при этом теперь никем не гарантируется, что будет работать принцип подстановки Лисков, даже несмотря на схожесть сигнатур интерфейса, семантика его реализаций может быть различной (собственно в COM даже рекомендуется давать наименования методам с неопределённым смыслом, чтобы каждая реализация интерфейса могла их интерпретировать по своему). Тоже самое касается и наследования интерфейсов, должен соблюдаться не только сигнатурный контракт, но и гарантированно семантический, а для этого класс A, должен содержать реализацию интерфейсов и child и parent. Цитата Qraizer @ Или "...класс A, должен содержать реализацию интерфейсов и child и parent" как раз и надо понимать "...что результат: incompatible types"? Именно, должно быть так: ![]() ![]() IParent = interface end; IChild = interface(IParent) end; TTest = class(TInterfacedObject, IParent, IChild)//класс должен содержать обе реализации интерфейсов end; TTest = class(TInterfacedObject, IChild)//а так будет в дальнейшем 'incompatible types' end; |
|
Сообщ.
#2350
,
|
|
|
|
Цитата MyNameIsIgor @ Цитата D_KEY @ То есть методов еще нет - ты их только создаешь. Так что и сливать тебе еще нечего. Но они должны быть - интерфейсы требуют. Вопрос в том, разные это будут методы или нет. Так методы(сами по себе) ничем не отличаются друг от друга. Цитата Цитата D_KEY @ Не должен, а можешь. Вернее это поведение по умолчанию Это очень странное поведение. В адрес подобного дизайна языка я могу сказать лишь маты ![]() Можешь пояснить? В первую очередь интересует разница с концептами(ведь для них будет именно такое поведение по умолчанию). Цитата А интерфейс - это разве не просто множество методов(а также атрибутов и внутренних типов, если язык поддерживает)? В таком случае, чем они отличаются от абстрактных классов? Цитата D_KEY @ А что их отличает друг от друга? Эти методы принадлежат разным интерфейсам. Ну, или если мы говорим исключительно с точки зрения теории то разные интерфейсы требуют реализации этих методов. |
|
Сообщ.
#2351
,
|
|
|
|
Цитата D_KEY @ А каким образом это будет возможно? Да и в случае интерфейса тоже не понятно, как это может быть? Ведь класс не наследует от интерфейса, а реализует интерфейс. Цитата D_KEY @ Но это уже разруливание проблемы множественного наследования, а не интерфейсов. Qraizer, вот кстати, D_KEY похоже дело говорит Тебе отсутствие такой ситуации не нравится в Delphi? ![]() ![]() class A { public: virtual void f() { cout << "A.f"; }; }; class B { public: virtual void f() { cout << "B.f"; }; }; class AB: A, B { }; int _tmain(int argc, _TCHAR* argv[]) { AB ab; ab.f(); //Ошибка, Member is ambiguous: 'A::f' and 'B::f' return 0; } Так у нас она по определению отсутствует, нет множественного наследования - нет наследования реализаций, в Delphi это решается агрегацией, а там, как я уже показывал, проблемы случайного перекрытия нет ![]() А просто в реализации одноименных методов от разных интерфейсов - мы с вами не отличаемся. ![]() ![]() class A { public: virtual void f() = 0; }; class B { public: virtual void f() = 0; }; class AB: A, B { public: virtual void f() { cout << "AB.f"; }; }; int _tmain(int argc, _TCHAR* argv[]) { AB ab; ab.f(); return 0; } |
|
Сообщ.
#2352
,
|
|
|
|
Ну а в делфи так можно ???
![]() ![]() int main(int argc, char *argv[]) { AB ab; ab.A::f();//все ок ... ab.B::f();//все ок ... return 0; } |
|
Сообщ.
#2353
,
|
|
|
|
Цитата wo1f @ Ну а в делфи так можно ??? Да, один в один (пример с агрегацией 5-10 стр. назад). |
|
Сообщ.
#2354
,
|
|
|
|
Ну так это с агрегацией... А тут множественное наследование. т.е. лишних объектов нет..
|
|
Сообщ.
#2355
,
|
|
|
|
Цитата wo1f @ Ну так это с агрегацией... А тут множественное наследование. т.е. лишних объектов нет.. И? В Delphi нет множественного наследования. Скопипастил пример: ![]() ![]() type IA = interface procedure f; end; IB = interface procedure f; end; A = class(TInterfacedObject, IA) procedure f; end; B = class(TInterfacedObject, IB) procedure f; end; SuperClass = class(TInterfacedObject, IA, IB) strict private FA: IA; FB: IB; public constructor Create; property RA: IA read FA implements IA; property RB: IB read FB implements IB; end; procedure A.f; begin Writeln( 'A.f' ); end; procedure B.f; begin Writeln( 'B.f' ); end; constructor SuperClass.Create; begin FA := A.Create; FB := B.Create; end; var x : SuperClass; begin x := SuperClass.Create; x.RA.f; x.RB.f; |