Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.156] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 301 302 [303] 304 305 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#4531
,
|
|
|
|
Цитата scorpion @ Я не вижу их реализации. В С++ ты просто получишь ошибку линковки, если даже просто начнешь использовать объекты класса B, естественно вызывая методы которые не имеют реализации . Спасибо, я вообще-то на С++, в основном пишу, так что в курсе. Думал, что отсутствия =0 будет достаточно, чтобы меня поняли Цитата Цитата D_KEY @ Кстати, и то, чтобы метод класса, реализующий метод интерфейса, был виртуальным, не требуется. Кстати в С++ тоже самое, чтобы метод класса, реализующий метод интерфейса был виртуальным, не требуется. Метод будет виртуальным, просто можно опускать спецификатор virtual для унаследованных методов. |
|
Сообщ.
#4532
,
|
|
|
|
Цитата D_KEY @ Метод будет виртуальным, просто можно опускать спецификатор virtual для унаследованных методов. Да, что ты тогда имелл ввиду, я просто видимо непонял до конца твою мысль? |
|
Сообщ.
#4533
,
|
|
|
|
Цитата scorpion @ Цитата D_KEY @ Метод будет виртуальным, просто можно опускать спецификатор virtual для унаследованных методов. Да, что ты тогда имелл ввиду, я просто видимо непонял до конца твою мысль? То, что ты реализуешь метод интерфейса не сделает метод твоего класса виртуальным, в отличие от С++. |
|
Сообщ.
#4534
,
|
|
|
|
Цитата D_KEY @ То, что ты реализуешь метод интерфейса не сделает метод твоего класса виртуальным, в отличие от С++. Это проблема? |
|
Сообщ.
#4535
,
|
|
|
|
Цитата D_KEY @ То, что ты реализуешь метод интерфейса не сделает метод твоего класса виртуальным, в отличие от С++. Ага. При программировании на шарпе я на это натыкался. Заоверлоадить ты можешь только то, что в базовом классе помечено как virtual. И к интерфейсам это не имеет никакого отношения. |
|
Сообщ.
#4536
,
|
|
|
|
Цитата scorpion @ Это проблема? Это очередной пример, показывающий концептуальное отличие интерфейсов от абстрактных классов. |
|
Сообщ.
#4537
,
|
|
|
|
Цитата scorpion @ Но ведь нужно понимать, что это своего рода синтаксический сахар. Ведь, может возникнуть неоднозначная ситуация, когда ты наследуешься от интерфейса и двух классов, и при этом эти классы никак не наследуются от интерфейса, но при этом во всех трех сущностях присутствует метод Foo, тогда как автоматически связывать? Имеено по этому в С++ этот подход не требуется, имхо. Но это никак не противоречит концепции интерфейсов. Я нигде не встречал в описании интерфейсов именно такой отличительной черты от абстрактных классов. Это синтаксический сахар и не более, я так считаю. Ты не наследуешься о интерфейса. Ты его реализуешь. Это концептуальная разница. По сути, интерфейс - это просто декларация того, что ты должен уметь. Контракт с клиентом. |
|
Сообщ.
#4538
,
|
|
|
|
Цитата scorpion @ А на шарпе или в делфи это все отработает без ошибок хочешь сказать? Компилятор сам реализует методы интерфейса чтоле? И в Delphi да. Добавлено scorpion В догонку тебе, запроси интерфейс, неизвестный на этапе компиляции, у объекта, тоже неизвестного на этапе компиляции. ![]() ![]() type IFoo = Interface ['{3F7C961B-FFFB-4142-AAB5-C0D654EE09D0}'] procedure Foo; end; IBar = Interface ['{D0CFA163-6017-4E78-A370-DA403A368D3C}'] procedure Bar; end; TFoo = class(TInterfacedObject, IFoo) public procedure Foo; end; TBar = class(TInterfacedObject, IBar) public procedure Bar; end; procedure TFoo.Foo; begin Writeln('TFoo.Foo'); end; procedure TBar.Bar; begin Writeln('TBar.Bar'); end; var SomeObj: TObject; SomeIntf: TGUID; BarIntf: IBar; FooIntf: IFoo; begin SomeObj := TBar.Create; SomeIntf := IBar; if SomeObj.GetInterface(SomeIntf, BarIntf) then BarIntf.Bar; SomeObj := TFoo.Create; SomeIntf := IFoo; if SomeObj.GetInterface(SomeIntf, FooIntf) then FooIntf.Foo; SomeObj := TBar.Create; SomeIntf := IFoo; if SomeObj.GetInterface(SomeIntf, FooIntf) then FooIntf.Foo else WriteLn('SomeObj не реализует интерфейс IFoo'); ReadLn; end. ![]() ![]() TBar.Bar TFoo.Foo SomeObj не реализует интерфейс IFoo Добавлено Цитата scorpion @ Ведь, может возникнуть неоднозначная ситуация, когда ты наследуешься от интерфейса и двух классов, и при этом эти классы никак не наследуются от интерфейса, но при этом во всех трех сущностях присутствует метод Foo, тогда как автоматически связывать? Там, где существуют интерфейсы - нет множественного наследования Добавлено Цитата DesweR @ В догонку тебе, запроси интерфейс, неизвестный на этапе компиляции, у объекта, тоже неизвестного на этапе компиляции. И да, верю, что можно, но хотелось бы взглянуть, как это на C# выглядит. |
|
Сообщ.
#4539
,
|
|
|
|
Цитата D_KEY @ Это очередной пример, показывающий концептуальное отличие интерфейсов от абстрактных классов. Покажи конкретно, документацию(вики, или еще какой источник), где написано что это концептуальное отличие интернфейсов от абстрактных классов ? Или ты исходишь из того как оно работает в шарпе? Причем тут полиморфизм и интерфейсы в частности? Цитата Flex Ferrum @ Ты не наследуешься о интерфейса. Ты его реализуешь. Это концептуальная разница. По сути, интерфейс - это просто декларация того, что ты должен уметь. Контракт с клиентом. Погоди, а как же ты собрался тогда работать с интерфейсом, если у него нет наследника в лице класса, реализующего интерфейс? А если и есть, то какой тогда смысл в интерфейсе, если есть класс, который полностью содержит реализацию интерфейса? В чем смысл? На вики, я не увидел эту концептуальную разницу, что еще посоветуете почитать? Давай зайдем с другой стороны. Вот есть интерфейс, и есть класс его реализующий: ![]() ![]() public interface IFoo { void Foo(); void Bar(); } public class Base { public void Foo() {/* something */} public void Bar() {/* something */}; } Продемонстрируй пожалуйста, как я могу использовать этот интерфейс с уже готовой реализацией в лице Base, но без введения новых линий наследования? Ведь как я понял, ты утверждаешь что именно в этом и есть концептуальное отличие от абстрактных классов. Добавлено Цитата DesweR @ Там, где существуют интерфейсы - нет множественного наследования В приведенном примере флекса, множественное наследование налицо. Или ты не заметил? Цитата DesweR @ В догонку тебе, запроси интерфейс, неизвестный на этапе компиляции, у объекта, тоже неизвестного на этапе компиляции. Зачем? |
|
Сообщ.
#4540
,
|
|
|
|
Цитата scorpion @ Покажи конкретно, документацию(вики, или еще какой источник), где написано что это концептуальное отличие интернфейсов от абстрактных классов ? Тут тебе это наглядно показали. Читай книги по языкам, где есть интерфейсы - Java, C# и т.п. Цитата Оно везде так работает.Или ты исходишь из того как оно работает в шарпе? Цитата Погоди, а как же ты собрался тогда работать с интерфейсом, если у него нет наследника в лице класса, реализующего интерфейс? Есть класс, реализующий интерфейс, но этот класс не наследует от интерфейса. Добавлено Цитата scorpion @ В приведенном примере флекса, множественное наследование налицо. Это т.н. "наследование интерфейсов", которое следует отличать от наследования реализаций(классов). |
|
Сообщ.
#4541
,
|
|
|
|
Цитата D_KEY @ Тут тебе это наглядно показали. Читай книги по языкам, где есть интерфейсы - Java, C# и т.п. Мне показали синтаксический сахар, и не более. А речь как я понимаю идет об интерфейсах в общем смысле этого слова. Так причем тут конкретные реализации интерфейсов в java и C# ? Цитата D_KEY @ Оно везде так работает. Где это написано? Я на той же вики этого не нашел. Вот например читаем: Цитата Использование интерфейсов возможно двумя способами: * Класс может реализовывать интерфейс. Реализация интерфейса заключается в том, что в описании класса данный интерфейс указывается как реализуемый, а в коде класса обязательно определяются все методы, которые описаны в интерфейсе, в полном соответствии с сигнатурами из описания этого интерфейса. То есть, если класс реализует интерфейс, для любого экземпляра этого класса существуют и могут быть вызваны все описанные в интерфейсе методы. Один класс может реализовать несколько интерфейсов одновременно. * Возможно объявление переменных и параметров методов как имеющих тип-интерфейс. В такую переменную или параметр может быть записан экземпляр любого класса, реализующего интерфейс. Если интерфейс объявлен как тип возвращаемого значения функции, это означает, что функция возвращает объект класса, реализующего данный интерфейс. Как правило, в объектно-ориентированных языках программирования интерфейсы, как и классы, могут наследоваться друг от друга. В этом случае интерфейс-потомок включает все методы интерфейса-предка и, возможно, добавляет к ним свои собственные. Таким образом, с одной стороны, интерфейс — это контракт, который обязуется выполнить класс, реализующий его, с другой стороны, интерфейс — это тип данных, потому что его описание достаточно четко определяет свойства объектов, чтобы наравне с классом типизировать переменные. Следует, однако, подчеркнуть, что интерфейс не является полноценным типом данных, так как он задаёт только внешнее поведение объектов. Внутреннюю структуру и реализацию заданного интерфейсом поведения обеспечивает класс, реализующий интерфейс; именно поэтому «экземпляров интерфейса» в чистом виде не бывает, и любая переменная типа «интерфейс» содержит экземпляры конкретных классов. Использование интерфейсов — один из вариантов обеспечения полиморфизма в объектных языках и средах. Все классы, реализующие один и тот же интерфейс, с точки зрения определяемого им поведения, ведут себя внешне одинаково. Это позволяет писать обобщённые алгоритмы обработки данных, использующие в качестве типов параметры интерфейсов, и применять их к объектам различных типов, всякий раз получая требуемый результат. ... Как правило, языки программирования разрешают наследовать интерфейс от нескольких интерфейсов-предков. Все методы, объявленные в интерфейсах-предках, становятся частью объявления интерфейса-потомка. В отличие от наследования классов, множественное наследование интерфейсов гораздо проще реализуется и не вызывает существенных затруднений. Тем не менее, одна коллизия при множественном наследовании интерфейсов и при реализации нескольких интерфейсов одним классом всё-таки возможна. Она возникает, когда в двух или более интерфейсах, наследуемых новым интерфейсом или реализуемых классом, имеются методы с одинаковыми сигнатурами. Разработчики языков программирования вынуждены выбирать для таких случаев те или иные способы разрешения противоречий. Вариантов здесь несколько: запрет на реализацию, явное указание конкретного и реализация базового интерфейса или класса. * Запрет. В одном классе просто запрещается реализовывать несколько интерфейсов, имеющих методы с одинаковыми сигнатурами. Если для какого-то класса требуется комбинация несовместимых интерфейсов, программист должен выбрать другой путь решения проблемы, например, выделить несколько классов, каждый из которых реализует один из необходимых интерфейсов, и использовать их экземпляры совместно. * Явное разрешение неоднозначности. В случае обнаружения компилятором коллизии от программиста требуется явно указать, метод какого из интерфейсов он реализует и вызывает. То есть одноимённые методы реализуются раздельно, а при вызове указывается, какой из них вызывается. При вызове одноимённых методов через переменную типа интерфейс неоднозначность не возникает, если использованный в качестве типа переменной интерфейс имеет только один метод с заданным именем. Вариантом этого решения является явное переименование для совпадающих по именам наследуемых или реализуемых методов, за счёт чего в пределах реализующего класса нет одноимённых методов, но при обращении через интерфейс всегда вызывается нужная реализация. * Общая реализация одноимённых методов. Если наследуется или реализуется несколько методов с одной и той же сигнатурой, то они объединяются в интерфейсе-наследнике, а в классе-реализаторе получают одну общую реализацию. Это хорошо подходит для случаев, когда одноимённые методы разных интерфейсов идентичны по предполагаемой функциональности, но может вызвать нежелательные эффекты, если поведение этих методов должно различаться. Где эта концептуальная разница описана? |
|
Сообщ.
#4542
,
|
|
|
|
Цитата DesweR @ Там, где существуют интерфейсы - нет множественного наследования Может, ещё и заявите, что оно не нужно? |
|
Сообщ.
#4543
,
|
|
|
|
Цитата scorpion @ Погоди, а как же ты собрался тогда работать с интерфейсом, если у него нет наследника в лице класса, реализующего интерфейс? А если и есть, то какой тогда смысл в интерфейсе, если есть класс, который полностью содержит реализацию интерфейса? В чем смысл? На вики, я не увидел эту концептуальную разницу, что еще посоветуете почитать? Почитай про примеси. Смысл интерфейса в том, что его могут реализовать разные объекты. Более того, как правило есть возможность подключить двоичную реализацию (по крайней мере в Delphi). Добавлено Цитата MyNameIsIgor @ Может, ещё и заявите, что оно не нужно? А много ты языков знаешь с множественным наследованием? Я навскидку назову C++ и Python (в котором еще и метаклассы примешали с извратом). |
|
Сообщ.
#4544
,
|
|
|
|
Цитата Romkin @ Смысл интерфейса в том, что его могут реализовать разные объекты. В С++ это сделать не проблема. Цитата Romkin @ Более того, как правило есть возможность подключить двоичную реализацию (по крайней мере в Delphi). А вот это уже не концептуальное отличие, это синтаксический сахар. |
|
Сообщ.
#4545
,
|
|
|
|
Цитата Romkin @ А много ты языков знаешь с множественным наследованием? А при чём тут их количество? Я спросил про нужность. Цитата Romkin @ Я навскидку назову C++ и Python Я бы ещё добавил OCaml, Perl, CL, Eiffel... |