La définition d'une méthode définie à l'origine dans la superbe classe, par définition signifie que cette méthode fera différentes choses lorsqu'elle sera invoquée sur un objet de la classe de base ou un objet de la sous-classe.
Cela signifie-t-il que des méthodes de remplacement toujours signifie violer le LSP? Ou y a-t-il des cas quand ce n'est pas?
Premier cas simple: ajouter de la mise en cache à une opération coûteuse. Il n'y a pas de différence fonctionnelle entre l'original et la nouvelle fonction.
De plus, la fonction d'origine pourrait être documentée pour faire quelque chose et tant que la fonction primordiale correspond toujours au sein de cette documentation, alors il n'y a pas de problème (le noyau du substitution principe). N'oubliez pas que vous devriez coder contre l'API et non la mise en œuvre.
Par définition différentes choses? Whaddayouean?
Liskov dit que vous ne devriez pas "aller contre" votre comportement de votre ancêtre. Cela ne signifie pas que vous ne pouvez pas l'étendre ou l'augmenter en faisant des choses en plus à ce comportement de base.
Dans votre méthode remplacée, vous appelez inherited
pour exécuter le comportement de l'ancêtre (honorant Liskov), puis peut faire des choses en plus de cela.
Ne pas appeler inherited
du tout (*) serait une violation de Liskov (à moins que vous ne renoncez pas à la mise en œuvre de la base, que je conseillerais vivement contre). Mise à jour @RatTatchetFreak a en fait un exemple assez soigné lorsqu'un descendant n'appellerait que hérité s'il n'avait pas déjà mis en cache un résultat pour un calcul autrement "coûteux".
(*) Veuillez noter que je suis habitué à une langue où vous pouvez appeler hérité, que l'ancêtre ou la méthode ancêtre est marquée abstraite. Le compilateur sort de l'appel.
Le principe de substitution de Liskov ne dit que que les sous-classes ne doivent pas violer Propriétés prouvables du Superype. Les propriétés prouvables sont fondamentalement les signatures de type des membres. Donc, si une méthode sur une superclasse est déclarée pour renvoyer un entier, il ne devrait pas être écrasé dans la sous-classe pour renvoyer une chaîne.
Les systèmes de type de type statiquement-dactylography OO Langues empêchent généralement de se produire, de sorte qu'un développeur ordinaire de dire C # code, vous ne devriez pas être trop inquiet de casser le LSP (bien que je pense qu'il y ait Quelques faiblesses du système de type concernant les tableaux qui vous permettent de casser le LSP).
Le principe est souvent compris plus largement (et vaguement) que les sous-classes ne devraient pas "casser des attentes", ce qui définitivement un bon principe de design, mais pas vraiment ce que le LSP dit.