10
votes

Vous ne pouvez pas affaiblir les conditions préalables et le renforcement des postconditions violer également le principe de substitution de Liskov?

la condition préalable réelle d'un sous-type est créée en combinant (à l'aide de logique ou ) conditions préalables d'un type de base et des conditions préalables d'un Sous-type , ce qui rend la la condition préalable résultante moins restrictive

postcondition réelle d'un sous-type est créé en combinant (à l'aide de logique et ) postconditions d'un type de base et postconditions d'un Sous-type , qui fait la postconditions suivantes plus restrictive

Voici des exemples de conditions préalables et affaiblissement postconditions , qui enfreignent le LSP (< Un href = "https://softwareengineering.stackexchange.com/questions/187613/how-does-stress-f-pre-conditions-and-àakening-of-post-conditions-violat"> link ):

  1. suppose que votre classe de base fonctionne avec un membre INT. Maintenant, votre sous-type nécessite que INT soit positif. Ceci est renforcé les pré-conditions, et maintenant n'importe quel code qui a fonctionné parfaitement bien avant l'intégration négative est cassé.

  2. De même, supposez le même scénario, mais la classe de base utilisée pour garantir que le membre serait positif après avoir été appelé. Puis Le sous-type change le comportement pour permettre des INT négatifs. Code que fonctionne sur l'objet (et suppose que la condition postérieure est positive int) est maintenant cassé car la condition postérieure n'est pas respectée.

    a) Pourquoi n'est-ce pas aussi considéré comme une violation de la LSP lorsque la méthode remplacée affaiblit une condition préalable , car cette méthode pourrait utiliser des paramètres qui ne sont pas acceptables pour le < EM> Contrats du type de base . En tant que tel, ne pouvions-nous pas prétendre que contrat de type BASE a été violé et, de suite, le LSP était également violé?

    b) Pourquoi n'est-ce pas aussi considéré comme une violation du LSP lorsque la méthode remplacée renforce , car les clients invoquent cette méthode ne recevra qu'un sous-ensemble de résultats possibles. de la méthode d'origine. En tant que tel, ne pouvions-nous pas prétendre que contrat de type BASE a été violé et, de suite, le LSP était également violé?

    Exemple:

    la classe de base postcontion garantit que la valeur de retour d'une méthode serait dans la plage 1-10 , mais ensuite le sous-type modifie la postcondition pour autoriser la valeur de retour pour être dans la plage 2-9 . Maintenant le code qui fonctionne sur l'objet renvoyé à partir de cette méthode (et suppose que le postcontion est dans une plage 1-10 ) est cassé depuis la postcontion n'est pas respecté.


0 commentaires

5 Réponses :


-1
votes

Je pense que votre exemple ne supporte pas votre point dans le sens suivant.

Dans l'INT négatif, exemple positif, ajout de nombres négatifs, bien qu'il inclue plus de possibilités affaiblit la garantie de la condition postérieure. Votre exemple genre de fait la même chose. Bien qu'il garantit une gamme plus étroite, il affaiblit toujours la garantie de la condition postérieure fournie par la classe de base.

La règle post-condition dit en fait:

cette règle indique que la méthode du sous-type fournit plus que la méthode SuperType: lorsqu'elle renvoie tout ce que la méthode SuperType fournirait est assurée, et peut-être des effets supplémentaires aussi bien (développement du programme en Java, P177)

Votre exemple ne garantit pas tout ce que le SuperType garantit. Je suppose que dans votre exemple de renforcement signifierait que le sous-type garantit que le retour du retour est de 1 à 10, il garantit en outre que le retour du retour est compris entre 2 et 9, pas seulement le second.


0 commentaires

-1
votes

Si le contrat de classe de base pour une méthode indique que l'appeler avec un nombre négatif lancera une exception, toute classe dérivée légitime devrait lancer la même exception si sa méthode est transmise un nombre négatif. Si, toutefois, le contrat de classe de base dit simplement qu'une méthode ne doit pas être appelée avec des nombres négatifs sans spécifier ce qui se passera si c'est le cas, une classe de base pourrait alors faire tout ce qu'il aime sans casser ce contrat.

Bien que cela puisse sembler inélégant d'avoir des conditions dans lesquelles le comportement d'une classe serait non spécifié, l'ajout de fonctionnalités à une classe tout en restant compatible vers le haut, nécessite généralement de changer les comportements non précisés dans ceux spécifiés. Dans certains cas, un comportement «non spécifié» sur une classe peut être «ne pas compiler», mais rien ne garantit que le code qui tente d'utiliser un tel membre ne parviendra toujours pas à compiler. Par exemple, si le contrat d'une classe ne fait aucune mention d'un membre "FOO", la tentative d'utilisation d'un tel membre pourrait probablement provoquer une erreur de compilation, mais une future version de la classe pourrait définir foo sans violer son contrat.


0 commentaires

-2
votes

Vous avez parfaitement raison. Les conditions préalables ne peuvent pas être affaiblies. Cela modifierait également le comportement du type de base. Par exemple:

class Base { void method(int x) { /* x: 1-100 allowed else exception  */ } }
class Weak: Base { void method(int x) { /* x: 1-1000  allowed else exception  */ } }
class Strong: Base { void method(int x) { /* x: 1-10  allowed else exception  */ } }

int Main() {
  Base base = new Base();
  base.method(101-1000); // exception

  Base base2 = new Weak();
  base2.method(101-1000); // ok

  Base base3 = new Strong();
  base3.method(101-1000); // exception 
}


1 commentaires

Il n'a pas de sens de comparer le comportement de la classe VS de la classe de base si vous enfreignez le contrat (1-100) de la classe de base en premier lieu. Le LSP ne s'applique que dans la spécification de la classe de base. L'absence de spécification est un comportement inconnu.



-1
votes

LSP signifie que vous devriez pouvoir substituer la classe de base avec la sous-classe pour les valeurs d'entrée en spécification. Il n'a pas de sens de comparer le comportement de la sous-classe VS de la classe de base lorsque vous enfreignez le contrat de la classe de base dans la première place (vous ne faites pas face à une véritable substitution si vous le faites).

(violation du contrat est un comportement inconnu, il arrive simplement que l'approche la plus courante consiste à jeter une exception.)

En ce qui concerne le renforcement de la postcondition, je ne vois pas votre point, vraiment (?) Si le contrat spécifie les valeurs 1-10, toutes les valeurs entre 1-10 sont de facto in-spécification, également 2-9 ou même 3 toujours (?)


0 commentaires

3
votes

Désolé, mais vous avez une erreur logique dans vos considérations.

La classe postcontion de la classe de base garantit la valeur de retour d'une méthode serait dans la plage 1-10, mais le sous-type change ensuite le postcondition pour permettre uniquement la valeur de retour d'être dans la plage 2-9.

Étant donné que le code fonctionne dans la plage 1-10 et la plage 2-9 est en fait dans la plage 1-10, Strenghtening La postcondition ne doit jamais être un problème.

même avec affaiblir les conditions préalables. Permettre au sous-type d'accepter une gamme plus grande ne casse pas le comportement du type de base. Depuis que le comportement est introduit uniquement dans le sous-type et uniquement comme condition préalable aux méthodes de sous-type.


0 commentaires