AlexBogy писал(а):
Я, видимо, некорректно выразился. Я писал о том, что расширение записи через агрегирование лично мне удобнее, чем через наследование, поскольку позволяет использовать поля с одинаковым именем. И просил высказать свое мнение более опытных программистов, как удобнее им.
Про компилятор - да, это отсылка к моему первому посту, мне было интересно, наследование через агрегирование привело бы к усложнению компилятора с точки зрения, например, проверки типов.
"Наследование через агрегирование" звучит довольно странно. Это два разных механизма, выражающие разные логические связи ("является" и "имеет"; "is" and "has").
Наследование используется, когда расширенная запись уточняет расширяемую в том смысле, в каком конкретное понятие уточняет общее понятие, добавляя конкретизирующие признаки. Есть "стул" вообще, а есть "деревянный стул" - добавлено уточнение материала, и
объём понятия сузился (уменьшилось число объектов реального мира, входящих в это понятие). Так же и с записями: есть просто устройство с PortNumber, а есть устройство, например, фирмы Сименс с PortNumber. Такое уточнение удобно выразить через наследование записи, добавляя недостающие признаки. Если понятийная сетка выбрана адекватно, у вас не будет желания переопределить смысл PortNumber или добавить ещё одно такое же поле. Если же понятия не соответствуют предметной области, нужно переосмыслить и перепроектировать.
Агрегирование используется, когда вам нужно собрать несколько понятий в один предмет, обычно с целью использования. Например, если вы хотите сказать, что на стуле кто-то сидит. Понятие человека не входит в понятие стула (человек не является стулом, и наоборот), но для практических целей между ними может быть установлена связь "сидит на". Или например, если вам нужно протоколировать (log) события, вы можете дать предмету некий "журнал" для ведения записей. Кто угодно может иметь журнал для записей, но не станете же вы все объекты делать разновидностями журналов и наследовать от типа "журнал" только ради доступа к этой функции (хотя видывал я и такой подход в отвратительно спроектированных системах).
Или, например, у вас есть понятие "порт связи", и у одного устройства может быть несколько портов связи - например, порт команд, порт сообщений и порт отладки. Это пример агрегации, а не наследования, так как устройство не является портом, а только лишь имеет порты.
Технически, с точки зрения компилятора, можно сказать, что наследование реализовано через агрегирование, в том смысле, что есть некое скрытое поле Parent родительского типа, доступ к полям которого ведётся без указания имени этого поля (Parent). Вы можете сделать несколько собственных таких полей и реализовать тем самым множественное наследование, и есть компиляторы (других языков, не Oberon), которые вам в этом помогут. Компилятор Оберона поддерживает выстраивание системы понятий со связью типа "является" (IS), и позволяет проверить, является ли объект представителем некого класса, что позволяет создать иерархическое дерево понятий.
Если вам полезно иметь несколько полей с одинаковым именем, то у меня есть вопросы к системе понятий, которыми вы оперируете. Лично мне никогда это ограничение не мешало, скорее наоборот, было поводом навести порядок мыслях и подходе к предметной области. Но это не означает, что у вас должно быть так же, вы же спросили про мой опыт. Если хотите, можете привести пример, и обсудим его более предметно.
Возвращаясь к началу, к отношениям "является" и "имеет", ваш пост можно прочесть как заявление, что вам удобнее моделировать предметную область только через отношение "имеет", и что отношение "является" представляется вам менее полезным. Что ж, в каком-то смысле любое понятие можно описать как "нечто" + набор признаков, которые это нечто "имеет": "стул - это нечто с 4 ножками и сиденьем". Рискну предположить, что абстракции в таком коде достаточно низкоуровневые и многословные. Проблема в том, что вам будет, во-первых, сложно выразить нечто относящееся именно и специфически к стульям, а во-вторых, всё четырёхногое от стула до кошки будет неразличимо. Но это уж мои фантазии, я и так уж слишком много написал. За сим откланяюсь.