Une classe LinkedList existe avec des fonctions telles que add_first (), add_last (), add_after (), remove_first (), remove_last () et remove ()
Il existe maintenant une classe Stack qui fournit des fonctionnalités telles que push (), pop (), peek () ou top (), et pour implémenter ces méthodes, elle étend les méthodes de la classe LinkedList. Est-ce une violation du principe de substitution de Liskov?
Par exemple, considérons le cas add_after () pour ajouter un nœud à la nième position d'une liste liée. Cela peut être fait dans la classe de base mais pas dans la classe Stack. Les postconditions sont-elles affaiblies ici ou modifiez-vous la méthode add_after () pour l'ajouter en haut de la pile?
En outre, si ce n'est pas une violation, est-ce une mauvaise conception? Et comment implémenteriez-vous la fonctionnalité Stack à l'aide de la classe LinkedList?
LinkedList
? Vous voudrez peut-être suivre les conseils d'un certain Joshua Bloch (qui a joué un rôle majeur dans la conception du cadre des collections Java) quand il a dit "Préférez la composition à l'héritage" - Peut-être avez-vous uneLinkedList
classe dans votre pile, mais ne l'étendez pas réellement?LinkedList
qui fait le gros du travail dans les coulisses (composition). De cette façon, les utilisateurs de votre code ne peuvent pas utiliser accidentellement une pile là où ils avaient besoin d'une liste ou vice versa.Réponses:
Non. Il est parfaitement possible d'ajouter des méthodes dans un sous-type.
Il s'agit d' une violation du LSP. Le LSP dit que les instances d'un sous-type doivent être substituables aux instances d'un sur-type sans changer les propriétés souhaitables d'un programme. Si un sous-type supprime une méthode, tout code qui appelle cette méthode se bloquera (ou obtiendra une
NoMethodError
exception, ou quelque chose du genre ). De toute évidence, "ne pas planter" est une propriété souhaitable.Modifier la
add_after()
méthode de cette manière est une violation de la règle d'historique (la plus importante des règles!) Et n'aide donc pas à corriger la violation du LSP.En utilisant la composition.
REMARQUE: tout ce que j'ai écrit ci-dessus s'applique uniquement aux langues qui confondent le sous-typage et le sous-classement! Le LSP concerne le sous - typage , pas le sous-classement. Dans une langue qui ne confondez pas les deux, il serait tout à fait acceptable de faire
Stack
une sous - classeLinkedList
, aussi longtemps que vous ne faites pas un sous - type deLinkedList
.la source
Comme tout a déjà été abordé par Jörg W Mittag, je développe un peu la partie suivante:
Fondamentalement, lorsqu'il y a une question de savoir si une hiérarchie viole LSP, cela dépend du contrat que vous posez. Alors, quel contrat
add_after
a? Si cela vous semble fou, comme "Ajouter un nœud à la n-ième position ou en haut", alors ça va, la post-condition est remplie, LSP n'est pas violé. Sinon, c'est une violation LSP.la source