Une classe devrait-elle connaître ses sous-classes? Une classe doit-elle faire quelque chose de spécifique pour une sous-classe donnée par exemple?
Mon instinct me dit que c'est une mauvaise conception, cela ressemble à un anti-modèle en quelque sorte.
Réponses:
La réponse impliquée par le concept de classes est "non".
Quelle que soit l'action, les données ou la relation que vous gérez fait partie de toutes les sous-classes - alors elles doivent être gérées dans la superclasse sans vérifier le type réel. Ou cela ne s'applique qu'à certaines sous-classes - alors vous devriez effectuer des vérifications de type au moment de l'exécution pour faire la bonne chose, la superclasse devrait être changée chaque fois que quelqu'un d'autre en hérite (ou elle pourrait silencieusement faire la mauvaise chose), les changements dans les classes dérivées peuvent casser la superclasse inchangée, etc.
En bref, vous obtenez un certain nombre de conséquences néfastes qui sont généralement suffisamment graves pour rejeter de telles solutions d'emblée. Si plusieurs de vos sous-classes font la même chose et que vous souhaitez éviter la duplication de code (pratiquement toujours une bonne chose), une meilleure solution consiste à introduire une classe de niveau intermédiaire à partir de laquelle toutes ces sous-classes peuvent hériter du code.
la source
Non seulement il ne devrait pas savoir, mais il ne peut tout simplement pas ! Habituellement, une classe peut être étendue à tout moment et en tout lieu. Il peut être étendu par des classes qui n'existaient même pas lors de son écriture.
Certaines langues permettent aux classes d'extension d'être contrôlées par la superclasse. Dans Scala, une classe peut être marquée comme
sealed
, ce qui signifie qu'elle ne peut être étendue que par d'autres classes au sein de la même unité de compilation (fichier source). Cependant, à moins que ces sous-classes ne soient égalementsealed
oufinal
, les sous-classes peuvent ensuite être étendues par d'autres classes.Dans Scala, ceci est utilisé pour modéliser des types de données algébriques fermés, donc le
List
type canonique de Haskell :peut être modélisé dans Scala comme ceci:
Et vous pouvez garantir que seulement ces deux exist « classes » sous - car
List
estsealed
et ne peut donc pas être étendue en dehors du fichier,Cons
estfinal
et ne peut donc pas être étendue à tous etNil
est unobject
qui ne peut être prolongé de toute façon.Mais il s'agit d'un cas d'utilisation spécifique (modélisation de types de données algébriques via l'héritage) et même dans ce cas, la superclasse ne connaît pas réellement ses sous-classes. C'est plus une garantie pour l' utilisateur du
List
type que s'il fait une discrimination de casNil
etCons
, il n'y aura pas d' autre alternative surgissant derrière son dos.la source
abstract internal
membre.La réponse simple est non.
Il rend le code fragile et annule deux principes de base de la programmation orientée objet.
la source
Oui, parfois. Par exemple, lorsqu'il existe un nombre limité de sous-classes. Un modèle de visiteur est une illustration de l'utilité de cette approche.
Exemple: un nœud de syntaxe abstraite (AST) d'une grammaire bien définie peut tous être hérités d'une seule
Node
classe implémentant un modèle de visiteur pour gérer tous les types de nœuds.la source
Node
classe de base , bien sûr, ne contient aucune référence directe à ses sous-classes. Mais il contient uneaccept
méthode avec unVisitor
paramètre. EtVisitor
contient unevisit
méthode pour chaque sous-classe. Ainsi, bien qu'ilNode
n'ait aucune référence directe à ses sous-classes, il les "connaît" indirectement, via l'Visitor
interface. Ils se sont tous couplés à travers elle.Si j'écris un composant pour une entreprise et plus tard, après mon départ, quelqu'un le prolonge à ses propres fins dois-je en être informé?
Non!
Même chose avec les cours. Faites confiance à votre instinct.
la source