Должен ли класс знать о своих подклассах? Должен ли класс делать что-то специфичное для данного подкласса, например?
Мои инстинкты говорят мне, что это плохой дизайн, это похоже на какой-то анти-паттерн.
Должен ли класс знать о своих подклассах? Должен ли класс делать что-то специфичное для данного подкласса, например?
Мои инстинкты говорят мне, что это плохой дизайн, это похоже на какой-то анти-паттерн.
Ответы:
Ответ, подразумеваемый понятием классов, - «нет».
Независимо от того, какое действие, данные или отношение вы обрабатываете, является частью всех подклассов - тогда они должны обрабатываться в суперклассе без проверки фактического типа. Или это применимо только к некоторым подклассам - тогда вам придется выполнять проверки типов во время выполнения, чтобы сделать правильные вещи, суперкласс должен быть изменен всякий раз, когда кто-то другой наследует его (или он может молча делать неправильные вещи), изменения в производных классах могут сломать неизменный суперкласс и т. д.
Короче говоря, вы получаете ряд плохих последствий, которые, как правило, достаточно плохи, чтобы отклонить такие решения из-под контроля. Если несколько ваших подклассов делают одно и то же, и вы хотите избежать дублирования кода (практически всегда это хорошо), лучшим решением будет введение класса среднего уровня, от которого все эти подклассы могут наследовать код.
источник
Мало того, что он не знает, он просто не может ! Обычно класс может быть расширен в любое время и в любом месте. Это может быть расширено классами, которые даже не существовали, когда это было написано.
Некоторые языки позволяют расширять классы, контролируемые суперклассом. В Scala класс может быть помечен как
sealed
, что означает, что он может расширяться только другими классами в пределах того же модуля компиляции (исходного файла). Однако, если эти подклассы также не являютсяsealed
илиfinal
, подклассы могут быть дополнительно расширены другими классами.В Scala это используется для моделирования замкнутых алгебраических типов данных, поэтому канонический
List
тип Haskell :можно моделировать в Scala следующим образом:
И вы можете гарантировать, что существуют только эти два подкласса, потому что он
List
естьsealed
и, следовательно, не может быть расширен за пределы файла,Cons
естьfinal
и, следовательно, не может быть расширен вообще, иNil
он неobject
может быть расширен в любом случае.Но это особый вариант использования (моделирование алгебраических типов данных посредством наследования), и даже в этом случае суперкласс фактически не знает о своих подклассах. Это больше гарантия для потребителя от
List
типа, если он делает случай дискриминацииNil
иCons
, не будет какой - либо другой альтернативы выскакивать за его спиной.источник
abstract internal
члена.Простой ответ - нет.
Это делает код хрупким и нарушает два основных принципа объектно-ориентированного программирования.
источник
Иногда да. Например, когда существует ограниченное количество подклассов, существуют. Паттерн посетитель является иллюстрацией полезности этого подхода.
Пример: узлы абстрактного синтаксического дерева (AST) некоторой четко определенной грамматики могут быть все унаследованы от одного
Node
класса, реализующего шаблон посетителя для обработки всех типов узлов.источник
Node
класс, конечно, не содержит прямых ссылок на свои подклассы. Но он содержитaccept
метод сVisitor
параметром. ИVisitor
содержитvisit
метод для каждого подкласса. Таким образом, несмотря на то, чтоNode
он не имеет прямых ссылок на свои подклассы, он «знает» о них косвенно, черезVisitor
интерфейс. Они все связаны вместе через это.Если я напишу компонент для фирмы и позже, после того как я уйду, кто-то расширит его для своих собственных целей, должен ли я быть проинформирован об этом?
Нет!
То же самое с классами. Доверяй своим инстинктам.
источник