Re[13]: Утиные истории vs ООП?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.10.05 14:03
Оценка:
Здравствуйте, eao197, Вы писали:

AVK>>Есть. Только сходство с наследованием классов чисто внешнее. По сути же это просто такое ограничение.


E>Правда?


Правда.

E> А зачем тогда наследование интерфейсов вообще?


Удобный констрейнт, позволяющий к тому же делать прозрачный downcasting.

AVK>>Нет, не то же самое. Все намного глубже и интереснее. На самом деле наличие реализовываемого интерфейса означает что компилятор создает специальную таблицу, interface map, которая отображает методы интерфейса на методы класса.


E>Тоже самое, имхо, происходит в C++ когда мы наследуемся от абстрактного класса без данных. Таблицу виртуальных функций ведь не я сам строю.


Нет, не то же самое (если лезть в детали, то вызов интерфейса обладает двойной косвенностью, а не одинарной, как в случае обычного виртуального вызова). В случае наследования класса мы приобретаем массу всего — код, данные. В случае реализации интерфейса ничего такого не происходит, мы всего лишь декларируем то, что некий класс обладает определенным публичным интерфейсом и ничего сверх того.

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


E>Точно так же и в duck typing.


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

E> Как только ставим на подставку груз больше расчетного -- получаем исключение. Все то же самое.


А если это не чемодан, а люк мусоропровода? Получим что телевизор улетит в неизвестном направлении.

AVK>>Не забывай о том, что львиная доля проверок выполняется в compile time.


E>Если duck typing встраивается в статически типизированный язык, то получаем те же самые проверки.


Нет, не получаем, потому что нет формального контракта, связанного с сигнатурой. Совпадение сигнатуры еще ничего не означает. А если мы такой формальный контракт введем, то получим интерфейсы — вид сбоку.
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re[11]: Утиные истории vs ООП?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.10.05 14:03
Оценка: +1
Здравствуйте, eao197, Вы писали:

AVK>>Да нет, как раз в том и суть duck typing, что мы сужаем ОО-контракт ввиде публичного интерфейса до сигнатуры методов.


E>Да нет, как раз в том и суть duck typing, что это уже и не ОО.


Контракт это тоже не обязательно ОО.

E>Поэтому оценивать duck typing с точки зрения ОО не совсем корректно.


Зачем тогда вы его описываете с точки зрения ОО? И что тогда за тип имеется ввиду (duck typing)?
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re[14]: Утиные истории vs ООП?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.10.05 14:17
Оценка:
Здравствуйте, AndrewVK, Вы писали:

E>> А зачем тогда наследование интерфейсов вообще?


AVK>Удобный констрейнт, позволяющий к тому же делать прозрачный downcasting.


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

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


E>>Точно так же и в duck typing.


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


Я имел в виду, что мы получаем исключение в результате действия, начатого в каком-то методе поставить_телевизор_на_опору. Этот метод не выполнит своих действий, а уже из-за чего -- это дело следователей. То, что исключение порождено в Чемодан.принять_груз или в СтеклянныйЖурнальныйСтолик.принять_груз -- это уже последствия того, что метод поставить_телевизор_на_опору выбрал неподходящую подставку. И наличие интерфейсов здесь нам никак не поможет. Если только мы не ввидем классификацию вроде: ненадежные_подставки, надежные_подставки, очень_надежные_подставки. Хотя это уже явно маразматический путь развития.

E>> Как только ставим на подставку груз больше расчетного -- получаем исключение. Все то же самое.


AVK>А если это не чемодан, а люк мусоропровода? Получим что телевизор улетит в неизвестном направлении.


А какая разница? Повторю, что метод поставить_телевизор_на_опору почему-то посчитал, что опора для этих целей подходит. А она не подошла.

E>>Если duck typing встраивается в статически типизированный язык, то получаем те же самые проверки.


AVK>Нет, не получаем, потому что нет формального контракта, связанного с сигнатурой. Совпадение сигнатуры еще ничего не означает. А если мы такой формальный контракт введем, то получим интерфейсы — вид сбоку.


+-

Все же осмысленная сигнатура много чего значит. И если у разных классов сигнатуры методов совпадают, то это не спроста.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: Утиные истории vs ООП?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.10.05 14:17
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>>>Да нет, как раз в том и суть duck typing, что мы сужаем ОО-контракт ввиде публичного интерфейса до сигнатуры методов.


E>>Да нет, как раз в том и суть duck typing, что это уже и не ОО.


AVK>Контракт это тоже не обязательно ОО.


Согласен, но у тебя было написано ОО-контракт.

E>>Поэтому оценивать duck typing с точки зрения ОО не совсем корректно.


AVK>Зачем тогда вы его описываете с точки зрения ОО? И что тогда за тип имеется ввиду (duck typing)?


Так ведь я не зря озаглавил тему "Утиные истории vs ООП". Чтобы понять, как между собой соотносятся ООП и duck typing при разработке приложений.

Под типом понимается объект с методами. Но если наследование -- это один из постулатов ООП, то в Duck typing можно обходится и без наследования.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[15]: Утиные истории vs ООП?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.10.05 14:29
Оценка:
Здравствуйте, eao197, Вы писали:

AVK>>Удобный констрейнт, позволяющий к тому же делать прозрачный downcasting.


E>Ну да ладно.

E>Хотя тоже самое можно сказать и про обычное наследование. В смысле прозрачного downcasting-а.

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

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


E>Я имел в виду, что мы получаем исключение в результате действия, начатого в каком-то методе поставить_телевизор_на_опору. Этот метод не выполнит своих действий, а уже из-за чего -- это дело следователей.


Опять же неформализуемо. Как определить выполнено ли действие, если чужой класс черный ящик? И как определить что он попутно не выполнил чего лишнего? А как сходу понять, что исключение "ЧемоданЭбсолютлиКрешед" из-за того, что мы на него телевизор поставили, а не потому что вчера соседский кот туда нассал?

E> То, что исключение порождено в Чемодан.принять_груз или в СтеклянныйЖурнальныйСтолик.принять_груз -- это уже последствия того, что метод поставить_телевизор_на_опору выбрал неподходящую подставку. И наличие интерфейсов здесь нам никак не поможет.


В случае наличия интерфейсов вместо сообщения о поломке чемодана мы получим сообщение о том, что телевизор на чемодан ставить нельзя. Сразу все понятно.

AVK>>А если это не чемодан, а люк мусоропровода? Получим что телевизор улетит в неизвестном направлении.


E>А какая разница?


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

E> Повторю, что метод поставить_телевизор_на_опору почему-то посчитал, что опора для этих целей подходит. А она не подошла.


А как определить что не подошла? Каков формальный критерий подходимости? Вот с интерфейсом все просто — если реализован, значит создатель класса рассчитывал на такое применение. И если будут проблемы, то это уже банальный баг в этом классе.

E>Все же осмысленная сигнатура много чего значит.


Тем не менее полагаться на это нельзя. В случае интерфейса в документации явно сказано что он означает. А вот под сигнатурой каждый производитель может понимать что то свое.
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re[13]: Утиные истории vs ООП?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.10.05 14:40
Оценка:
Здравствуйте, eao197, Вы писали:

AVK>>Контракт это тоже не обязательно ОО.


E>Согласен, но у тебя было написано ОО-контракт.


Потому что твое описание тоже от ОО плясало.

AVK>>Зачем тогда вы его описываете с точки зрения ОО? И что тогда за тип имеется ввиду (duck typing)?


E>Так ведь я не зря озаглавил тему "Утиные истории vs ООП". Чтобы понять, как между собой соотносятся ООП и duck typing при разработке приложений.


Да пофигу как озаглавил. Главное что внутри топика ты от ОО не отходишь.

E>Под типом понимается объект с методами.


Ну все, дальше можно говорить только в терминах ООП.

E> Но если наследование -- это один из постулатов ООП,


Знаешь, я в этом не уверен. Впрочем это терминологический спор.
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re[16]: Утиные истории vs ООП?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.10.05 14:49
Оценка:
Здравствуйте, AndrewVK, Вы писали:

E>>Ну да ладно.

E>>Хотя тоже самое можно сказать и про обычное наследование. В смысле прозрачного downcasting-а.

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


В случае абстрактных базовых классов в C++, в которых нет ничего кроме чистых виртуальных методов, разницы между наследованием и реализацией интерфейса нет никакой. Поэтому я и считаю, что interface в Java -- это не более, чем удобный синоним длинному определению "абстрактный класс, в котором есть только чистые виртуальные методы" в C++. А все остальное то же самое.

AVK>Опять же неформализуемо. Как определить выполнено ли действие, если чужой класс черный ящик? И как определить что он попутно не выполнил чего лишнего?


С интерфейсом все то же самое. Или уже есть интерфейсы, где явно говорится, что вот этот метод не имеет побочных эффектов?

AVK> А как сходу понять, что исключение "ЧемоданЭбсолютлиКрешед" из-за того, что мы на него телевизор поставили, а не потому что вчера соседский кот туда нассал?


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

E>> То, что исключение порождено в Чемодан.принять_груз или в СтеклянныйЖурнальныйСтолик.принять_груз -- это уже последствия того, что метод поставить_телевизор_на_опору выбрал неподходящую подставку. И наличие интерфейсов здесь нам никак не поможет.


AVK>В случае наличия интерфейсов вместо сообщения о поломке чемодана мы получим сообщение о том, что телевизор на чемодан ставить нельзя. Сразу все понятно.


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

E>> Повторю, что метод поставить_телевизор_на_опору почему-то посчитал, что опора для этих целей подходит. А она не подошла.


AVK>А как определить что не подошла? Каков формальный критерий подходимости?


Не случилось исключения. И все работает после действия как надо.

AVK> Вот с интерфейсом все просто — если реализован, значит создатель класса рассчитывал на такое применение. И если будут проблемы, то это уже банальный баг в этом классе.


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

Здесь проблемы у того, кто этот класс для неподходящих целей использует.

E>>Все же осмысленная сигнатура много чего значит.


AVK>Тем не менее полагаться на это нельзя. В случае интерфейса в документации явно сказано что он означает. А вот под сигнатурой каждый производитель может понимать что то свое.


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

В случае же с интерфейсами мы находимся в подобной ситуации. Сначала мы должны понять, какой интерфейс нам использовать. Потом убедится, что все нужные нам классы этот интерфейс реализуют. Затем, что реализуют их так как нам нужно (без нежелательных побочных эффектов). Если кто-то не реализует, а нам хотелось бы, то мы делаем вокруг него обертку. Чтобы в конце-концов получить тот же самый результат.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[14]: Утиные истории vs ООП?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.10.05 15:00
Оценка:
Здравствуйте, AndrewVK, Вы писали:

E>>Так ведь я не зря озаглавил тему "Утиные истории vs ООП". Чтобы понять, как между собой соотносятся ООП и duck typing при разработке приложений.


AVK>Да пофигу как озаглавил. Главное что внутри топика ты от ОО не отходишь.


А зачем мне отходить, если я хочу понять, где у duck typing-а есть преимущества над ООП, а где недостатки.

E>>Под типом понимается объект с методами.


AVK>Ну все, дальше можно говорить только в терминах ООП.


E>> Но если наследование -- это один из постулатов ООП,


AVK>Знаешь, я в этом не уверен. Впрочем это терминологический спор.


Так я, вроде, уже давно обозначил позицию: Re[4]: Утиные истории vs ООП?
Автор: eao197
Дата: 07.10.05

ООП базируется на трех китах: инкапсуляция, наследование и полиморфизм.

Термин ООП я употребляю именно в этой интерпритации. Поэтому, если есть объект и есть методы (с полиморфизмом), но нет наследования (в принципе), то это уже не ООП.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[10]: Утиные истории vs ООП?
От: Dyoma Россия http://www.livejournal.com/users/dyomap/
Дата: 12.10.05 15:00
Оценка: 5 (1)
Здравствуйте, AndrewVK, Вы писали:

D>>От контратка прямо сразу никто не отказывается.


AVK>Да нет, как раз в том и суть duck typing, что мы сужаем ОО-контракт ввиде публичного интерфейса до сигнатуры методов.

Именно это (выделенное жирным) я и имел ввиду.

D>> Изменяется область применимости (scope) контракта, все методы названные одинакого должны выполнять один контракт.


AVK>Кому должны? Компилятор не в состоянии проконтроллировать это. А значит мы задачу по контролю семантической совместимости возлагаем на программиста.


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

D>> Это похоже на перегрузку, если в одно интерфейсе (или классе) есть методы с одинаковым именем, но разными типами параметров, естественно ожидать, что делают эти методы, что-то очень похожее.


AVK>Совсем не похоже. Перегрузка сосредоточена внутри одного класса,


Я ж начал того, что scope контракта расширяется, теперь это дело не одного класса/интерфейса, а всего проекта.

AVK> так что если ты там что то напортачил, то сам дурак.


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

AVK>А вот duck typing взаимодействует с чужим классом, который не обязан знать ничего о том как ты интерпретируешь конкретную сигнатуру. Говоря проще — в первом варианте инкапсуляция не нарушается, а во втором нарушается.


Во-первых еще раз о scope. А во-вторых, инкапсуляция это касается только того, как метод что-то делает, а не того что он делает.

D>>Тут вообще-то нужна дополнительная поддержка от языка. Т.к. контрактов на методы может быть много, то и названий должно быть много, и в языке должно быть естественно использование длинных имен методов (речь конечно не про названия f, g, и т.п.).


AVK>Это все подпорки. Гарантию несовпадения тебе дадут только гуиды.


Не совсем подпорки, все-таки это скорее решение проблемы, см. дальше.

AVK>Только вот с интерфейсами оно как то проще.


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

D>> В Smalltalk эта проблема решена, имена методов естественным образом длинные, и проблем с пересечением названий для разных контрактов достаточно мало, что бы не мешать.


AVK>От это вряд ли.


Это не вряд ли, это факт.

AVK> Видишь ли, тут проблема не столько в том, что методы случайно совпали по сигнатуре, сколько в том что разные программисты могут интерпретировать одну и ту же сигнатуру по разному. Что бы этого не произошло нужно конкретные сигнатуры описывать формально, с указанием в комментариях/документации что под этой сигнатурой понимается. Чувствуешь к чему пришли?


А теперь о "подпорках". Вот я взял один из Smalltalk`ов (DolphinSmalltalk) и посмортел среднюю длинну имени метода (по библиотеке). Среднее арифметическое по различным именам, получилось больше 16 символов. Общее число (различных) имен методов почти 13000. Согласись 13000 — это очень большой словарный запас в него очень много понятий (в нашем случае контрактов) может поместиться.
Насчет коментрариев/документации — это опять же не зависит от наличия типов. Если ты вводишь какой-то новый контрак, ты должен дать другим возможность узнать что ты имел ввиду.

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


D>>Согласен в том смысле, что duck-typing стоит вводить в язык в версии 1.0, когда на нем еще ничего не написано, существенно закладываясь на типы.


AVK>Наоборот. Если проектировать с нуля, то duck typing совершенно бесполезен. Он оправдан только если мы не можем менять существующие наработки. Об этом я применительно к C# 3.0 в этом топике уже писал.


Я писал про версию языка 1.0, а не проекта. И имел ввиду, что если сразу разработчики библиотек не будут озабочены выбором уникальных имен для разных контрактов, то потом, смысла от duck-typing действительно будет существенно меньше.

Dyoma
ALMWorks
http://deskzilla.com/
Re[17]: Утиные истории vs ООП?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.10.05 15:22
Оценка:
Здравствуйте, eao197, Вы писали:

E>В случае абстрактных базовых классов в C++, в которых нет ничего кроме чистых виртуальных методов, разницы между наследованием и реализацией интерфейса нет никакой.


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

AVK>>Опять же неформализуемо. Как определить выполнено ли действие, если чужой класс черный ящик? И как определить что он попутно не выполнил чего лишнего?


E>С интерфейсом все то же самое.


Нет. Потому что интерфейс это не просто синтаксическая конструкция, это вполне конкретная сущность с вполне конкретной семантикой.

E> Или уже есть интерфейсы, где явно говорится, что вот этот метод не имеет побочных эффектов?


В описании интерфейса.

AVK>> А как сходу понять, что исключение "ЧемоданЭбсолютлиКрешед" из-за того, что мы на него телевизор поставили, а не потому что вчера соседский кот туда нассал?


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


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

AVK>>А как определить что не подошла? Каков формальный критерий подходимости?


E>Не случилось исключения.


Фиговый критерий, надо сказать.

E> И все работает после действия как надо.


А как надо? Как это проконтроллировать? Опять перекладывать все на плечи программиста, т.е. юнит-тесты писать?

AVK>> Вот с интерфейсом все просто — если реализован, значит создатель класса рассчитывал на такое применение. И если будут проблемы, то это уже банальный баг в этом классе.


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


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

AVK>>Тем не менее полагаться на это нельзя. В случае интерфейса в документации явно сказано что он означает. А вот под сигнатурой каждый производитель может понимать что то свое.


E>Но ведь, если мы знаем с объектами каких типов нам предстоит работать


А знаем ли?

E> (вспомним, что программа -- это все таки реализация одной часной задачи)


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

E> и оказывается, что методы с одинаковыми сигнатурами в них выполняют нужные нам действия, то мы просто их используем.


А как проверить что все существующие классы с такими сигнатурами делают то же самое? Эскпериментально проверять их все? И что делать, если потом кто то другой будет добавлять новые классы, ничего не зная о твоей механике?

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


Выбрать метод с нужной сигнатурой.

E> Потом убедится, что все нужные нам классы этот интерфейс реализуют.


Убедится что все нужные классы этот метод содержат.

E> Затем, что реализуют их так как нам нужно (без нежелательных побочных эффектов).


Затем, что реализуют именно то, что нужно.
Затем, что реализуют их так как нам нужно (без нежелательных побочных эффектов).

E> Если кто-то не реализует, а нам хотелось бы, то мы делаем вокруг него обертку.


Если кто-то не реализует, а нам хотелось бы, то мы делаем вокруг него обертку.

E> Чтобы в конце-концов получить тот же самый результат.


А если у нас несколько связанных методов (чуть более сложный контракт), то для duck typing повторяем все для каждого метода.
Как видишь, в случае duck typing все только сложнее.
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re[15]: Утиные истории vs ООП?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.10.05 15:22
Оценка:
Здравствуйте, eao197, Вы писали:

AVK>>Да пофигу как озаглавил. Главное что внутри топика ты от ОО не отходишь.


E>А зачем мне отходить, если я хочу понять, где у duck typing-а есть преимущества над ООП, а где недостатки.


Не может у него быть преимуществ над ООП. Эти понятия ортогональны.

E>>> Но если наследование -- это один из постулатов ООП,


AVK>>Знаешь, я в этом не уверен. Впрочем это терминологический спор.


E>Так я, вроде, уже давно обозначил позицию: Re[4]: Утиные истории vs ООП?
Автор: eao197
Дата: 07.10.05

E>

E>ООП базируется на трех китах: инкапсуляция, наследование и полиморфизм.

E>Термин ООП я употребляю именно в этой интерпритации. Поэтому, если есть объект и есть методы (с полиморфизмом), но нет наследования (в принципе), то это уже не ООП.

А теперь вернемся к топику — я постоянно упоминаю о том, что наследование в рассмотрение вопроса включать не стоит. Ты же его пытаешься постоянно втащить. И ты же заявляешь:

AVK>Да нет, как раз в том и суть duck typing, что мы сужаем ОО-контракт ввиде публичного интерфейса до сигнатуры методов.
E>Да нет, как раз в том и суть duck typing, что это уже и не ОО.

Так при чем тут, черт возьми, наследование, если я говорю о контракте? Что, duck typing отменяет понятие контракта (обрати внимание, не интерфейса, а контракта)?
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re[11]: Утиные истории vs ООП?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.10.05 15:43
Оценка:
Здравствуйте, Dyoma, Вы писали:

AVK>>Кому должны? Компилятор не в состоянии проконтроллировать это. А значит мы задачу по контролю семантической совместимости возлагаем на программиста.


D>Эта задача и так лежит на программисте, никакой компилятор не проверяет, что за бред написан в реализации такого-то метода.


Видишь ли, в случае интерфейсов мы делаем это ровно один раз, когда реализуем тот или иной интерфейс. Все, дальше не наша проблема. Мы использовали определенный контракт, если кто то его реализовал не так, как это предписано, это его личная проблема.
А в случае duck typing нам нужно проконтроллировать контракт каждого используемого метода, причем постоянно эту процедуру повторять в том случае, если список используемых типов расширяется. Веселье наступает, если duck typing начинает использоваться несколькими независимыми механиками поверх одного типа.

D> Проверка типов проверяет только есть ли у заявленного типа методы с таким-то именем, а уж для чего он использован — дело только программиста.


Ты про duck typing?

AVK>>Совсем не похоже. Перегрузка сосредоточена внутри одного класса,


D>Я ж начал того, что scope контракта расширяется, теперь это дело не одного класса/интерфейса, а всего проекта.


Контракта проекта с чем, позвольте спросить?

AVK>> так что если ты там что то напортачил, то сам дурак.


D>А как насчет пользователя этого метода? Особенно в ситуации, когда параметры перегруженных методов связаны по иерархии и явным приведением типа в месте вызова можно повлиять на то какой метод будет вызван?


Еще раз повторюсь — класс это черный ящик, что находится внутри него личное дело разработчика этого класса. Пользователю остается только в точности следовать объявленному контракту. А вот в случае duck typing у нас такого контракта нет. Никто тебе не гарантирует что метод Add добавляет элемент в коллекцию и нечего более во всех классах которые использует и будет использовать в будущем твой алгоритм. Нет такого места, где написано — во всем проекте метод Add делает это и только это. Или есть?

AVK>>Только вот с интерфейсами оно как то проще.


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


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

AVK>> Видишь ли, тут проблема не столько в том, что методы случайно совпали по сигнатуре, сколько в том что разные программисты могут интерпретировать одну и ту же сигнатуру по разному. Что бы этого не произошло нужно конкретные сигнатуры описывать формально, с указанием в комментариях/документации что под этой сигнатурой понимается. Чувствуешь к чему пришли?


D>А теперь о "подпорках". Вот я взял один из Smalltalk`ов (DolphinSmalltalk) и посмортел среднюю длинну имени метода (по библиотеке). Среднее арифметическое по различным именам, получилось больше 16 символов. Общее число (различных) имен методов почти 13000. Согласись 13000 — это очень большой словарный запас в него очень много понятий (в нашем случае контрактов) может поместиться.


Прочти еще раз, плиз, то что я написал. Ты меня просто не понял.

D>Насчет коментрариев/документации — это опять же не зависит от наличия типов. Если ты вводишь какой-то новый контрак, ты должен дать другим возможность узнать что ты имел ввиду.


Безусловно. Но, что характерно, в одно месте, в описании интерфейса. Все, все остальные нарушать единожды объявленный контрак не имеют права. А duck typing предлагает подобный контракт в каждом используемом классе, и все такие классы надо контроллировать.
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re[18]: Утиные истории vs ООП?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.10.05 15:50
Оценка:
Здравствуйте, AndrewVK, Вы писали:

E>> Или уже есть интерфейсы, где явно говорится, что вот этот метод не имеет побочных эффектов?


AVK>В описании интерфейса.


Видимо, мы по разному понимаем понятие побочных эффектов.

AVK>Ну вот о том и речь, что нужно гадать что там произошло и по какой причине.


Да не нужно гадать, из-за чего чемодан развалился. Гадать нужно почему на него телевизор поставили.

AVK>>>А как определить что не подошла? Каков формальный критерий подходимости?


E>>Не случилось исключения.


AVK>Фиговый критерий, надо сказать.


А есть другие критерии?

E>> И все работает после действия как надо.


AVK>А как надо? Как это проконтроллировать? Опять перекладывать все на плечи программиста, т.е. юнит-тесты писать?


А как вообще контролировать, что программа работает? Если не брать какие-то формальные математические доказательства. Что мы делаем, чтобы убедится в том, что в ней нет ошибок?

AVK>>> Вот с интерфейсом все просто — если реализован, значит создатель класса рассчитывал на такое применение. И если будут проблемы, то это уже банальный баг в этом классе.


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


AVK>Наличие реализации интерфейса означает что класс рассчитан на использование этого интерфейса. Если класс не выполняет заявленный контракт, то это проблемы этого класса.


Ну выполняет он, выполняет. Этот несчастный столик является "подставкой". И если на него поставить вазу или телефон, то он справляется со своей задачей.

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

E>>Но ведь, если мы знаем с объектами каких типов нам предстоит работать


AVK>А знаем ли?


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

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

AVK>Что не мешает разрабатывать решение не одному человеку, а команде, и не одномоментно, а на протяжении определенного промежутка времени.


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

E>> и оказывается, что методы с одинаковыми сигнатурами в них выполняют нужные нам действия, то мы просто их используем.


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


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

Да, это плохой критерий, я согласен с тобой.
Но, видимо, в случае duck typing-а другого нет.

<...перечисление действий в случае duck typing...>

AVK>А если у нас несколько связанных методов (чуть более сложный контракт), то для duck typing повторяем все для каждого метода.

AVK>Как видишь, в случае duck typing все только сложнее.

Может быть. Но duck typing начинает оправдываться, если у нужных нам типов нет изначально одинакового интерфейса -- ну не мы эти типы делали. В duck typing-е нам не потребуется унифицировать эти различия в общем интерфейсе.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[16]: Утиные истории vs ООП?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.10.05 15:50
Оценка:
Здравствуйте, AndrewVK, Вы писали:

E>>А зачем мне отходить, если я хочу понять, где у duck typing-а есть преимущества над ООП, а где недостатки.


AVK>Не может у него быть преимуществ над ООП. Эти понятия ортогональны.


Или паралелльны.

E>>Так я, вроде, уже давно обозначил позицию: Re[4]: Утиные истории vs ООП?
Автор: eao197
Дата: 07.10.05

E>>

E>>ООП базируется на трех китах: инкапсуляция, наследование и полиморфизм.

E>>Термин ООП я употребляю именно в этой интерпритации. Поэтому, если есть объект и есть методы (с полиморфизмом), но нет наследования (в принципе), то это уже не ООП.

AVK>А теперь вернемся к топику — я постоянно упоминаю о том, что наследование в рассмотрение вопроса включать не стоит. Ты же его пытаешься постоянно втащить.


Да потому, что мне это важно. Я ведь топик начал c:

Так вот мне интересно, не является ли Duck typing следующей парадигмой после ООП? Ведь в duck typing нет отношения "is-a", а есть что-то типа "like-a" ("can", "respond_to"). Т.е., наследования нет, а полиморфизм, благодоря динамической типизации, есть.


и тут я придерживаюсь следующего:
-- ООП без наследования, это не ООП;
-- в данном топике мне интересно противопоставление duck typing и ООП.

Но если нет наследования, то это уже не ООП и сравнивать duck typing с чем-то, что не есть ООП, я еще не пробовал.

AVK> И ты же заявляешь:

AVK>

AVK>>Да нет, как раз в том и суть duck typing, что мы сужаем ОО-контракт ввиде публичного интерфейса до сигнатуры методов.
E>>Да нет, как раз в том и суть duck typing, что это уже и не ОО.

AVK>Так при чем тут, черт возьми, наследование, если я говорю о контракте? Что, duck typing отменяет понятие контракта (обрати внимание, не интерфейса, а контракта)?

Контракта не отменяет. А что такое ОО-контракт, про сужение которого ты говорил?
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: Утиные истории vs ООП?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.10.05 16:06
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Безусловно. Но, что характерно, в одно месте, в описании интерфейса. Все, все остальные нарушать единожды объявленный контрак не имеют права. А duck typing предлагает подобный контракт в каждом используемом классе, и все такие классы надо контроллировать.


Т.е. это нас приводит к тому, что в приложении мы должны оперировать двумя разными понятиями: интерфейс (контракт) и реализация (класс). Мы не можем создать класс без того, чтобы ранее определить его интерфейс. Т.е., если мне нужен класс "чемодан", то я сначала должен определить интерфейс "чемодан", а затем сделать его реализацию в виде класса "обычный_чемодан". Как следствие, место создания экземпляра я должен максимально локализововать (чтобы имя "обычный_чемодан" было только где-нибудь в одном месте программы), а везде, где мне нужен чемодан, я должен оперировать только интерфейсом "чемодан". Так получается?
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[19]: Утиные истории vs ООП?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.10.05 16:18
Оценка:
Здравствуйте, eao197, Вы писали:

E>>> Или уже есть интерфейсы, где явно говорится, что вот этот метод не имеет побочных эффектов?


AVK>>В описании интерфейса.


E>Видимо, мы по разному понимаем понятие побочных эффектов.


Видимо ты не понял о каких эффектах шла речь. Я говорил не о том, что метод не полностью описывается контрактом, а о том, что (в полиморфном коде) нет никакой гарантии что за методом Add стоит именно то, что тебе кажется правильным.

AVK>>Ну вот о том и речь, что нужно гадать что там произошло и по какой причине.


E>Да не нужно гадать, из-за чего чемодан развалился. Гадать нужно почему на него телевизор поставили.


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

AVK>>>>А как определить что не подошла? Каков формальный критерий подходимости?


E>>>Не случилось исключения.


AVK>>Фиговый критерий, надо сказать.


E>А есть другие критерии?


В случае интерфейса критерий очень простой — интерфейс реализован. Поскольку реализация интерфейса подразумевает не просто наличие определенного набора методов с определенной сигнатурой, но и то, что эти методы делают определенные вещи.

AVK>>А как надо? Как это проконтроллировать? Опять перекладывать все на плечи программиста, т.е. юнит-тесты писать?


E>А как вообще контролировать, что программа работает? Если не брать какие-то формальные математические доказательства. Что мы делаем, чтобы убедится в том, что в ней нет ошибок?


Вариантов много. Один из — контроль соотвествия контрактов компилятором и рантаймом. В случае интерфейса формальный контракт есть, в случае duck typing нету, потому что с сигнатурой никакой семантики не связано.

AVK>>Наличие реализации интерфейса означает что класс рассчитан на использование этого интерфейса. Если класс не выполняет заявленный контракт, то это проблемы этого класса.


E>Ну выполняет он, выполняет. Этот несчастный столик является "подставкой". И если на него поставить вазу или телефон, то он справляется со своей задачей.


Если заявлена реализация интерфейса подставки, то он обязан либо работать в таковом качестве, либо выкинуть ArgumentOutOfRangeException. Потому что создатель класса знает что класс будет использован в качестве подставки.
А вот если у нас duck typing, то черт его знает, что конкретный класс, который может быть известен в рантайме, под этим будет понимать.

E>>>Но ведь, если мы знаем с объектами каких типов нам предстоит работать


AVK>>А знаем ли?


E>Кажется есть такое понятие: "локальность ссылок". Если бы не оно, программирование на динамических языках действительно представляло бы из себя сплошной глюкодром. Но ведь это не так.


Спорный вопрос

E> А не так потому, что вмешивается в дело "локальность ссылок" -- объекты используются в очень ограниченных контекстах, где легко отслеживать их типы.


Звучит круто, но совершенно непонятно. Как ты в полиморфном коде собираешься отслеживать типы? А если система компонентная?

E>Так я думаю, что пока в проекте подобная "локальность" существует, то мы действительно знаем с чем работаем.


Мне кажется, что ты подразумеваешь, что весь проект делает один человек или маленькая команда высококвалифицированных пспецов.

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


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


Вопрос в объеме таких проверок.

E>Да, это плохой критерий, я согласен с тобой.

E>Но, видимо, в случае duck typing-а другого нет.

Вот поэтому duck typing и не кажется мне идеей, которую можно применять широко. В определенных случаях вполне оправданно, но только в очень определенных.

E>Может быть. Но duck typing начинает оправдываться, если у нужных нам типов нет изначально одинакового интерфейса -- ну не мы эти типы делали.


Ну ты же сам говорил — всегда можно создать обертку. Да, это сложнее, но при том и значительно надежнее. А в качестве бонуса получаем возможность подкорректировать поведение метода конкретного класса/набора классов, если оно не полностью соответствует ожидаемому. Да и не много на практике случаев, когда методы с одинаковой сигнатурой и похожей семантикой есть, а общего интерфейса нет. Так вот, навскидку, в .NET Framework я такого не припомню.
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re[17]: Утиные истории vs ООП?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.10.05 16:22
Оценка:
Здравствуйте, eao197, Вы писали:

E>и тут я придерживаюсь следующего:

E>-- ООП без наследования, это не ООП;

Спорно.

E>-- в данном топике мне интересно противопоставление duck typing и ООП.


Ты все таки определись. Противопоставление ООП или все же противопоставление классическим ООПным контрактам — интерфейсам и базовым классам.

E>Контракта не отменяет. А что такое ОО-контракт, про сужение которого ты говорил?


Я говорил про сужение просто контракта.
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re[15]: Утиные истории vs ООП?
От: Dyoma Россия http://www.livejournal.com/users/dyomap/
Дата: 12.10.05 16:33
Оценка: 1 (1)
Здравствуйте, eao197, Вы писали:

E>>> Но если наследование -- это один из постулатов ООП,


AVK>>Знаешь, я в этом не уверен. Впрочем это терминологический спор.


E>Так я, вроде, уже давно обозначил позицию: Re[4]: Утиные истории vs ООП?
Автор: eao197
Дата: 07.10.05

E>

E>ООП базируется на трех китах: инкапсуляция, наследование и полиморфизм.

E>Термин ООП я употребляю именно в этой интерпритации. Поэтому, если есть объект и есть методы (с полиморфизмом), но нет наследования (в принципе), то это уже не ООП.

Вообще-то ООП это объекты, обменивающиеся сообщениями. Отсюда следуют только инкапуляция и полиморфизм — потому как утверждается, что объекту сообщение послать можно, а как он на него будет реагировать это его дело. Наследование же появляется не во всех ООЯ, а только в (хотя бы динамически) типизированных. И даже когда появляется, то по разным причинам и с разными целями. В статически типизированных языках, наследование (как минимум интерфейсов) является необходимым требованием системы типов. В динимически — это не более чем способ реюза кода, т.е. без него можно обойтись, все решения будут возможны, только местами по-другому реюзать. Например код:
class Base {
    void f() {...}
    void g() {...}
}
class Derived {
    void f() { super.f(); ...}
}

Меняем на:
сlass Base {
  void f() { BaseUtil.f(this); }
    void g() {...}
}
class Derived {
    void f() ( BaseUtil.f(this); ...}
}

Dyoma
ALMWorks
http://deskzilla.com/
Re[20]: Утиные истории vs ООП?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.10.05 16:35
Оценка:
Здравствуйте, AndrewVK, Вы писали:

E>>Видимо, мы по разному понимаем понятие побочных эффектов.


AVK>Видимо ты не понял о каких эффектах шла речь. Я говорил не о том, что метод не полностью описывается контрактом, а о том, что (в полиморфном коде) нет никакой гарантии что за методом Add стоит именно то, что тебе кажется правильным.


Странно, я думал, что в нашем разговоре это подразумевается.

AVK>>>Ну вот о том и речь, что нужно гадать что там произошло и по какой причине.


E>>Да не нужно гадать, из-за чего чемодан развалился. Гадать нужно почему на него телевизор поставили.


AVK>Для этого нужно понять что именно телевизор был причиной.


Так ведь в языках, в которых сильная поддержка run-time, мы об этом сразу узнаем. По stack trace.

AVK> А так телевизор поставили, он вроде стоит. Потом телевизор убрали. А через день он сам развалился, потому что телевизор поставили и кот нассал. И в гарантию не отнесешь, потому что в руководстве черным по белому написано — котам внутрь чемодана не ссать.


Извини, это другая ситуация. Мы до сих пор говорили, что телевизор поставили и опора разлетелась в пух и прах.

E>>А есть другие критерии?


AVK>В случае интерфейса критерий очень простой — интерфейс реализован. Поскольку реализация интерфейса подразумевает не просто наличие определенного набора методов с определенной сигнатурой, но и то, что эти методы делают определенные вещи.


Ты знаешь, это как расхождение теории с практикой. В теории (интерфейсы + проверка компилятора) все OK. На практике -- через несколько часов работы приложение падает.

AVK>Вариантов много. Один из — контроль соотвествия контрактов компилятором и рантаймом. В случае интерфейса формальный контракт есть, в случае duck typing нету, потому что с сигнатурой никакой семантики не связано.


Опять же, только реальные запуски могут подтвердить правильность программы.

AVK>>>Наличие реализации интерфейса означает что класс рассчитан на использование этого интерфейса. Если класс не выполняет заявленный контракт, то это проблемы этого класса.


E>>Ну выполняет он, выполняет. Этот несчастный столик является "подставкой". И если на него поставить вазу или телефон, то он справляется со своей задачей.


AVK>Если заявлена реализация интерфейса подставки, то он обязан либо работать в таковом качестве, либо выкинуть ArgumentOutOfRangeException.


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

E>> А не так потому, что вмешивается в дело "локальность ссылок" -- объекты используются в очень ограниченных контекстах, где легко отслеживать их типы.


AVK>Звучит круто, но совершенно непонятно.


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

AVK> Как ты в полиморфном коде собираешься отслеживать типы?


А зачем? Все типы run-time отслеживает. Я ведь говорю про строгую типизацию (как в Ruby/Python/Smalltalk).

AVK> А если система компонентная?


Вот не знаю. Есть у меня подозрение, что не все будет ладно в датском королевстве.

E>>Так я думаю, что пока в проекте подобная "локальность" существует, то мы действительно знаем с чем работаем.


AVK>Мне кажется, что ты подразумеваешь, что весь проект делает один человек или маленькая команда высококвалифицированных пспецов.


Про высококвалифицированных спецов не могу сказать. Пока я только про свой опыт сужу.

E>>Да, это плохой критерий, я согласен с тобой.

E>>Но, видимо, в случае duck typing-а другого нет.

AVK>Вот поэтому duck typing и не кажется мне идеей, которую можно применять широко. В определенных случаях вполне оправданно, но только в очень определенных.


Да, с этим я могу согласится. О чем и сказал: Re: Утиные истории vs ООП?
Автор: eao197
Дата: 07.10.05


Хотя кто его знает. У меня еще не было опыта проектирования больших систем сразу в терминах duck typing.

AVK>Да и не много на практике случаев, когда методы с одинаковой сигнатурой и похожей семантикой есть, а общего интерфейса нет. Так вот, навскидку, в .NET Framework я такого не припомню.


Имхо, .NET Framework -- это не очень хороший для данной темы пример. Все же в нем повторно реализованы многократно пройденные вещи.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[18]: Утиные истории vs ООП?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.10.05 16:40
Оценка:
Здравствуйте, AndrewVK, Вы писали:

E>>и тут я придерживаюсь следующего:

E>>-- ООП без наследования, это не ООП;

AVK>Спорно.


E>>-- в данном топике мне интересно противопоставление duck typing и ООП.


AVK>Ты все таки определись. Противопоставление ООП или все же противопоставление классическим ООПным контрактам — интерфейсам и базовым классам.


Да я вот смотрю в Wikipedia

Fundamental concepts of Object Oriented Programming

Object-oriented programming emphasizes the following concepts:

* Objects — Packaging data and functionality together into units within a running computer program; objects are the basis of modularity and structure in an object-oriented computer program. Objects are self contained and should be easily identifiable. This modularity should allow the program parts to correspond to aspects of the problem.
* Abstraction — The ability for a program to ignore some aspects of the information that it is manipulating, i.e. the ability to focus on the essential. Each object in the system serves as a model of an abstract "actor" that can perform work, report on and change its state, and "communicate" with other objects in the system, without revealing how these features are implemented. Processes, functions or methods may also be so abstracted, and when they are, a variety of techniques are required to extend an abstraction.
* Encapsulation — Ensures that users of an object cannot change the internal state of the object in unexpected ways; only the object's own internal methods are allowed to access its state. Each object exposes an interface that specifies how other objects may interact with it. Other objects will rely exclusively on the object's external interface to interact with it.
* Polymorphism via message sending. Instead of subroutine calls, object-oriented languages can make message sends; the specific method which responds to a message send depends on what specific object the message is sent to. For example, if a bird receives the message "move fast", it will flap its wings and fly. If a lion receives the same message, it will move its legs and run. Both answer the same request, but in ways appropriate to each creature. This gains polymorphism, because a single variable in the program text can hold different kinds of objects as the program runs, and thus the same program text can invoke different methods at different times in the same execution. To contrast, functional languages gain polymorphism through the use of first-class functions.
* Inheritance- Organizes and facilitates polymorphism and encapsulation by permitting objects to be defined and created that are specialized types of already-existing objects — these can share (and extend) their behavior without having to reimplement that behavior. (Object-based languages do not always have inheritance.)


Как-то без наследования я себе ООП не представляю.

E>>Контракта не отменяет. А что такое ОО-контракт, про сужение которого ты говорил?


AVK>Я говорил про сужение просто контракта.


Ok.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.