Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.156] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 142 143 [144] 145 146 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#2146
,
|
|
|
|
Цитата Shaggy @ А когда, собстно, они так не используются? Собственно и множественное наследование и интерфейсы используются в основном там, где нужно различное представление одного объекта (правда у множественного наследования классов сфера применения много выше, но основная всё таки эта). В общем то без возможности множественного наследования интерфейсов, последние бы просто не были бы нужны. приведи пример(и желательно не один) в котором интерфейсы используются именно в таком качестве... |
|
Сообщ.
#2147
,
|
|
|
|
Цитата D_KEY @ Не забывай, что в обсуждаемых языках(ну кроме С++) интерфейсы нужны в качестве костыля для обеспечения множественного наследования ![]() в делфи интерфейсы также служат средством интеграции делфи-объектов с COM/OLE Добавлено на Racket можно, часа через 2 могу показать, если что |
|
Сообщ.
#2148
,
|
|
|
|
это невозможно... класс может реализовать несколько интерфейсов, но не унаследоваться от них я о том, что имитация множественного наследования с помощью интерфейсов(implements, либо перекрытие QueryInterface) скорее исключение, чем правило ИМХО вспоминаются только TAggregatedObject/TContainedObject, но это ближе к СОМ, хотя и не обязательно Цитата D_KEY @ Интерфейс описан прямо в параметре, без явного задания имени интерфейса. Просто говорим, что наша функция(метод) принимает любой объект, у которого есть метод f, принимающий целое число и возвращающий целое число. что-то вроде шаблонной функции(или как там у вас оно называется)? это где-то уже есть(или опять сферический конь )?непонятно как оно будет работать в runtime... |
|
Сообщ.
#2149
,
|
|
|
|
Цитата Shaggy @ я о том, что имитация множественного наследования с помощью интерфейсов(implements, либо перекрытие QueryInterface) скорее исключение, чем правило ИМХО Зачем тогда нужны интерфейсы как явление в принципе? |
|
Сообщ.
#2150
,
|
|
|
|
Цитата korvin @ Ты притворяешься, не пойму? Это разные сообщения.это ООПшно, объект не может и не должен реагировать на одно и то же сообщение по-разному. Цитата DesweR @ Гм... А подумать?Вот только не надо про агрегацию тут. Мы о ней знаем, и для нас это всего лишь один из вариантов композиции. Это для вас это костыль, требующийся из-за отсутствия множественного наследования реализаций. Интересно попробовать найти поддержку среди корифеев ООПроектирования, которые тоже будут ратовать за реализицию иным средством композиции, нежели композиция интерфейсов. Попробуй передай агрегированный объект в функцию, принимающиую его интерфейс.В обоих ситуациях можно считать Программиста (хоть мне тоже не нравится молчание компилятора при совпадении имён, но тут иначе только хуже): а) На начальном проектирования не позаботился о именовании методов у классов, позиционируемых как "множествено-наследуемые". б) Выбрал классы изначально не позиционируемые как "множествено-наследуемые". Цитата IL_Agent @ Вот это уже интереснее. Требуется явная квалификация? А когда? Всегда или только при коллизиях?В C# это не так. При реализации придётся явно указать, от какого интерфейса взят метод. Цитата D_KEY @ Вот именно. Никто не будет обвинять C-программера, что для внешней функции своей библиотеки выбрал имя, совпадающее с именем другой функции другой библиотеки, если они обе понадобятся в одной программе. Так же, как никто не будет утверждать, что это теперь должна быть одна и та же функция. А вот решать эту коллизию придётся. Дельфи сливает функции в одну, korvin утверждает, что это нормально, DesweR, что виноват я, а ты - что виноваты авторы библиотек. И только C++ предлагает несложные пути решения коллизий "имеющимися средствами".Хотя я понимаю, что на практике такие коллизии бывают и их нужно разруливать, но это не от хорошей жизни. Ну, да, я сутрировал. Есть копипаст (фи), есть аггрегация (в данном контексе тоже фи, даже фу, скорее всего). Но счас не на эту тему. А вообще, D_KEY, да, да, концепты! Я их хочу! Пряс счас, ждать C++2x ну никак желания нету. |
|
Сообщ.
#2151
,
|
|
|
|
Цитата D_KEY @ На некотором абстрактном языке: ![]() ![]() f(interface { f(self, int)->int } object, int x) -> int { //... return object.f(10) } к сожалению на Racket такое показать не получится, потому что там два интерфейса с одинаковым набором методов фактически разные интерфейсы: ![]() ![]() > (equal? (interface () foo) (interface () foo)) #f а на Go запросто так можно: ![]() ![]() package main import "fmt" type S struct { x int } func (s S) foo(x int) { fmt.Print( x + s.x ) } func test(x interface { foo (x int) }) { x.foo(3) } func main() { var s S s.x = 1 test(s) } => ![]() ![]() 4 впрочем на Racket легко определить функцию, которая будет проверять соответствие объекта интерфейсу по именам методов, как в Go и юзать эту функцию в контрактах =) Цитата Qraizer @ Ты притворяешься, не пойму? Это разные сообщения. это одинаковые сообщения, сообщения идентифицируются только именем и списком параметров, т.е. сигнатурой. они не "принадлежат" интерфейсам, не "входят в пространство имен" интерфейса. Цитата Qraizer @ Интересно попробовать найти поддержку среди корифеев ООПроектирования, которые тоже будут ратовать за реализицию иным средством композиции, нежели композиция интерфейсов. многие современные языки предоставляют примеси и trait'ы Цитата Qraizer @ И только C++ предлагает несложные пути решения коллизий "имеющимися средствами". потому что в C++ нет интерфейсов, потому и нет такого поведения Цитата Qraizer @ Пряс счас, ждать C++2x ну никак желания нету. оффтоп Лисперы смеются над вами =)) |
|
Сообщ.
#2152
,
|
|
|
|
Цитата korvin @ Цитата Qraizer @ Пряс счас, ждать C++2x ну никак желания нету. оффтоп Лисперы смеются над вами =)) Скрытый текст Как же слаб голос столь ничтожного количества ![]() |
|
Сообщ.
#2153
,
|
|
|
|
Цитата Shaggy @ это невозможно... класс может реализовать несколько интерфейсов, но не унаследоваться от них Как не назови, но в обсуждаемых языках разница заключается лишь в ключевых словах(а иногда нет и их). Цитата я о том, что имитация множественного наследования с помощью интерфейсов(implements, либо перекрытие QueryInterface) скорее исключение, чем правило ИМХО Тогда можешь рассказать, в каких случаях ты используешь интерфейсы, а в каких абстрактные классы и в чем, на твой взгляд, между ними разница? Цитата Цитата D_KEY @ Интерфейс описан прямо в параметре, без явного задания имени интерфейса. Просто говорим, что наша функция(метод) принимает любой объект, у которого есть метод f, принимающий целое число и возвращающий целое число. что-то вроде шаблонной функции(или как там у вас оно называется)? это где-то уже есть(или опять сферический конь )?Быть может и есть. О теоретических предпосылках таких вещей читал когда-то... Сейчас чисто мои измышления, как я и говорил чуть выше Цитата непонятно как оно будет работать в runtime... Да ничего сложного. Концептуально это будет что-то вроде такого: ![]() ![]() class MyInterface { public: virtual int f(int) = 0; }; int f_impl(MyInterface &obj, int x) { //... return obj.f(x); } template<typename T> class MyInterfaceAdapter : public MyInterface { public: explicit MyInterfaceAdapter(T &object) : m_object(object) { } virtual int f(int x) // override { return m_object.f(x); } private: T &m_object; }; template<typename SomeType> int f(SomeType &object, int x) { MyInterfaceAdapter<SomeType> adapter; f_impl(adapter); } Как-то так. С дополнительными возможностями оптимизации со стороны компилятора. Добавлено Цитата korvin @ Цитата D_KEY @ На некотором абстрактном языке: ![]() ![]() f(interface { f(self, int)->int } object, int x) -> int { //... return object.f(10) } к сожалению на Racket такое показать не получится, потому что там два интерфейса с одинаковым набором методов фактически разные интерфейсы: ![]() ![]() > (equal? (interface () foo) (interface () foo)) #f Странно. А чем это обусловлено, не знаешь? Цитата Неплохо. Все-таки что-то приличное в этом странном язычке есть.а на Go запросто так можно: ![]() ![]() package main import "fmt" type S struct { x int } func (s S) foo(x int) { fmt.Print( x + s.x ) } func test(x interface { foo (x int) }) { x.foo(3) } func main() { var s S s.x = 1 test(s) } => ![]() ![]() 4 Цитата Зачем С++ интерфейсы такие, как в Java/C#?Цитата Qraizer @ И только C++ предлагает несложные пути решения коллизий "имеющимися средствами". потому что в C++ нет интерфейсов, потому и нет такого поведения Совершенно не нужны. Вот концепты бы... |
|
Сообщ.
#2154
,
|
|
|
|
Цитата D_KEY @ Странно. А чем это обусловлено, не знаешь? в смысле почему разработчики решили реализовать интерфейсы именно так? не знаю. вообще это проявляется только при попытке использовать стандартные предикаты проверки соответствия-объекта-интерфейсу/реализации-интерфейса-классом. вместо них, как я уже писал, можно использовать свои на манер Go |
|
Сообщ.
#2155
,
|
|
|
|
Цитата korvin @ Цитата D_KEY @ Странно. А чем это обусловлено, не знаешь? в смысле почему разработчики решили реализовать интерфейсы именно так? не знаю. Да, именно это я и имел в виду. Вообще приятно, когда знаешь, что в языке, откуда, зачем и почему. Тот же Мейер в своей книге по ООП подробно описал свою точку зрения по многим вопросам, поэтому всегда ясно, почему Eiffel такой, какой он есть. По С++ есть D&E, рассказывающая историю языка и объясняющая многие принятые в языке решения. Есть ли подобные книги по другим языкам? В частности по обсуждаемым C# и Delphi? |
|
Сообщ.
#2156
,
|
|
|
|
Цитата D_KEY @ Да, именно это я и имел в виду. Вообще приятно, когда знаешь, что в языке, откуда, зачем и почему. ну я думаю разработчики Racket просто не заморачивались и сделали интерфейсы структурами с парой-тройкой полей, т.е. форма interface по сути макра, раскрывающаяся в вызов конструктора структуры типа interface, ну а каждый вызов конструктора создает новый объект-структуру. |
|
Сообщ.
#2157
,
|
|
|
|
Цитата D_KEY @ Сейчас чисто мои измышления, как я и говорил чуть выше Цитата D_KEY @ Да ничего сложного. Концептуально это будет что-то вроде такого: но это же снижение надёжности(если я всё правильно понял) ты выкусываешь из интерфейса класса метод(ы) основываясь только на имени(возможно) и параметрах метода. переносишь обязанности создателя класса на пользователя кроме того, заголовок функции превращается в нечитаемую кашу.. |
|
Сообщ.
#2158
,
|
|
|
|
Цитата Shaggy @ Цитата D_KEY @ Сейчас чисто мои измышления, как я и говорил чуть выше Цитата D_KEY @ Да ничего сложного. Концептуально это будет что-то вроде такого: но это же снижение надёжности(если я всё правильно понял) ты выкусываешь из интерфейса класса метод(ы) основываясь только на имени(возможно) и параметрах метода. Еще раз прошу пояснить мне, в чем тогда принципиальная концептуальная разница между интерфейсом и абстрактным классом? Может я действительно что-то не понимаю в интерфейсах. Цитата переносишь обязанности создателя класса на пользователя Не понял. Мне нужен объект, который имеет некий интерфейс, о чем я и сообщаю компилятору. В чем проблема-то? А вот если мне нужен именно некоторый абстрактный тип данных, то я могу использовать механизм абстрактных классов. Цитата кроме того, заголовок функции превращается в нечитаемую кашу.. Ты всегда можешь задать синоним этого типа. Строгий или нет - зависит от задачи. |
|
Сообщ.
#2159
,
|
|
|
|
Цитата D_KEY @ Еще раз прошу пояснить мне, в чем тогда принципиальная концептуальная разница между интерфейсом и абстрактным классом? Может я действительно что-то не понимаю в интерфейсах. тем что объект это средство/инструмент для расширения контракта, а интерфейс, для его ограничения интерфейс является неделимой логической единицей этот пример я уже приводил, но всё же: (С++)child наследник parent и оба классы класс А наследник child процедура test принимающая в качестве параметра parent передаём в test экземпляр A, компилируется? а теперь то же самое для delphi, только child и parent интерфейсы результат: incompatible types Цитата D_KEY @ Мне нужен объект, который имеет некий интерфейс, о чем я и сообщаю компилятору. В чем проблема-то? а класс может предоставить такой интерфейс? где это написано? Цитата D_KEY @ Ты всегда можешь задать синоним этого типа. замечательно самому то не смешно?именовано-безымянный интерфейс |
|
Сообщ.
#2160
,
|
|
|
|
Цитата Shaggy @ Цитата D_KEY @ Еще раз прошу пояснить мне, в чем тогда принципиальная концептуальная разница между интерфейсом и абстрактным классом? Может я действительно что-то не понимаю в интерфейсах. тем что объект это средство/инструмент для расширения контракта Поясни, пожалуйста.Цитата а интерфейс, для его ограничения интерфейс является неделимой логической единицей Единицей чего? Цитата Ага. Почему нет?(С++)child наследник parent и оба классы класс А наследник child процедура test принимающая в качестве параметра parent передаём в test экземпляр A, компилируется? Цитата А почему? Какое логическое обоснование такому поведению?а теперь то же самое для delphi, только child и parent интерфейсы результат: incompatible types Разве A не реализует интерфейс parent? Зачем требовать явного указания этого? И, самое главное, какой от этого практический толк? Цитата Цитата D_KEY @ Мне нужен объект, который имеет некий интерфейс, о чем я и сообщаю компилятору. В чем проблема-то? а класс может предоставить такой интерфейс? где это написано? Какой класс? Цитата Ничего смешного не вижу. Есть в языке средство для описания интерфейсов, а есть для задания синонимов(или новых типов). Что не так?Цитата D_KEY @ Ты всегда можешь задать синоним этого типа. замечательно самому то не смешно?именовано-безымянный интерфейс Или если в языке есть, скажем, tuple, то задание для него синонима тоже вызывает у тебя смех? А синонимы для массивов? |