IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Principe de substitution de Liskov


Sujet :

Langage Java

  1. #1
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 311
    Par défaut Principe de substitution de Liskov
    Bonjour à tous ,

    J'ai un soucis de compréhension sur ce sujet fort utile et intéressant qu'est le principe de substitution de Liskov.

    Par exemple les classes suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public class Compteur0 { 
    // @effects initialise this a 0
    public Compteur0() { ... }
     
    // @return la valeur de this 
    public int getValue () { . . . }
     
    //@modifies this
    // @effects this_post > this 
    public void incr() { ... } }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    public class Compteur2 extends Compteur0 { 
     
    // @effects initialise this a 0
    public Compteur2() { ... }
     
    //@requires value > 0
    // @modifies this
    // @effects this_post = this + value
     public void incr(int value) { ... }
     
    // @modifies this
    // @throws NegativeValueException si value < 0 
    // @effects this_post = this  - value
     
    public void decr ( int value ) throws NegativeValueException { . . . } }
    La classe Compeur2 est-elle un sous-type légitime ? je veux dire elle respecte le principe de substitution de Liskov de la classe Compteur0?
    J'ai compris que ce principe se base sur la notion de super classe et sous-type en clair partout où j'attends un type de donnée Compteur0 et je passe Compteur2 tout doit se passer correctement si j'ai compris ?
    Mais concrètement ça reste floue ...

    Merci d'avance pour vos suggestions.

  2. #2
    Membre Expert Avatar de yildiz-online
    Homme Profil pro
    Architecte de domaine
    Inscrit en
    Octobre 2011
    Messages
    1 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte de domaine

    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 447
    Par défaut
    C'est correct oui, vu que tu peux remplacer le parent par l'enfant sans provoquer de comportement inattendu pour l'utilisateur (pas de changement de portée, pas de nouvelle exception).

    le LSP n'empêche pas d'ajouter des méthodes à une classe sans que celle ci ne l'hérite de ses parents, c'est utile par exemple pour des modules ou des implémentations sont utilisées entre-elles, avec leurs méthodes spécifiques, mais ce qui sera visible à l'extérieur ne sera de toute façon que la classe parent (ou l'interface).

  3. #3
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 311
    Par défaut
    Merci pour ta réponse ,

    J'ai des questions :

    C'est correct oui, vu que tu peux remplacer le parent par l'enfant sans provoquer de comportement inattendu pour l'utilisateur (pas de changement de portée, pas de nouvelle exception).
    Tu entends quoi par changement de portée et de nouvelle exception ?

    le LSP n'empêche pas d'ajouter des méthodes à une classe sans que celle ci ne l'hérite de ses parents
    C'est-à dire que je peux ajouter des méthodes dans Compteur2 sans pour autant qu'elles soient dans Compteur0 et sans que le comportement puisse changer ?

    mais ce qui sera visible à l'extérieur ne sera de toute façon que la classe parent (ou l'interface)
    Tu veux dire que si j'utilise la sous-type dans un parent l'accès aux méthodes visibles seront ceux de la classe parent à moins de caster ce dernier en sous-type ?

    Comment je peux démontrer que la classe Compeur2 est-elle un sous-type légitime ? je veux dire elle respecte le principe de substitution de Liskov de la classe Compteur0?

    Merci.

  4. #4
    Membre Expert Avatar de yildiz-online
    Homme Profil pro
    Architecte de domaine
    Inscrit en
    Octobre 2011
    Messages
    1 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte de domaine

    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 447
    Par défaut
    Par changement de portée, c'est la réduction de la visibilité d'une méthode (public dans le parent, package dans l'enfant par exemple)
    Par nouvelle exception, c'est l'introduction d'une exception vérifiée (qui étend Exception et non RuntimeException donc) dans une méthode de l'enfant qui serait absente du parent.

    Oui, tu peux avoir une classe abstraite Vehicule qui défini une méthode seDeplace avec comme enfants Voiture et Tracteur
    Voiture et Camion surchargent tous deux la méthode seDeplace, mais Tracteur introduit la méthode tracte.

    Tracteur respecte le LSP car si on instancie un Tracteur déclaré de type Vehicule, le contrat est respecté par la méthode seDeplace, et on peut le substituer par une Voiture.

    Pas besoin de caster en sous type, tu peux utiliser des classes dans leur type enfant à l'intérieur du module mais exposer uniquement l'interface vers l'extérieur.

    Pour démontrer il faut:
    -valider que les preconditions ne sont pas plus fortes dans la sous classe.
    -que les post conditions ne sont pas plus fortes dans le parent.
    -que la sous classe n'introduit pas de nouvelle exception

  5. #5
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 311
    Par défaut
    Merci pour tes explications

    Par changement de portée, c'est la réduction de la visibilité d'une méthode (public dans le parent, package dans l'enfant par exemple)
    Tu aurais un exemple concret ?

  6. #6
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    Ca va être compliqué de donner un exemple parce que le compilateur refuse de laisser passer une réduction de visibilité

    Si tu as une classe mère avec une méthode publique, les classes filles qui en héritent doivent aussi avoir cette méthode qui soit publique (par héritage ou override) : tu ne peux pas "masquer" la méthode en changeant sa visibilité dans la classe fille.


    Par contre, tu peux toujours augmenter la visibilité : si ta classe mère avait une méthode protected, les classes filles peuvent la surcharger en la déclarant publique (ce qui serait une horreur en terme de conception objet, mais c'est possible)

  7. #7
    Membre Expert Avatar de yildiz-online
    Homme Profil pro
    Architecte de domaine
    Inscrit en
    Octobre 2011
    Messages
    1 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte de domaine

    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 447
    Par défaut
    Citation Envoyé par Johnny P. Voir le message
    Merci pour tes explications



    Tu aurais un exemple concret ?
    Non, en java ce n'est pas possible, dans d'autres langages peut-être, mais c'est un exemple de ce qui pourrait être une précondition plus forte dans la sous classe, à savoir qu'il est plus restrictif d'utiliser la méthode que dans le parent.

    Le LSP est agnostique du langage, mais c'était un mauvais exemple dans ce cas.

  8. #8
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    Citation Envoyé par eulbobo Voir le message
    Ca va être compliqué de donner un exemple parce que le compilateur refuse de laisser passer une réduction de visibilité
    oui et non: il est possible qu'une sous-classe ne se comporte pas comme prévu -en particulier dans un contexte de module - (exemple: méthode ContextSensitive )

  9. #9
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 311
    Par défaut
    Par contre, tu peux toujours augmenter la visibilité : si ta classe mère avait une méthode protected, les classes filles peuvent la surcharger en la déclarant publique (ce qui serait une horreur en terme de conception objet, mais c'est possible)
    Effectivement à faire cela nous brisons le principe de ne pas exposer la représentation. Mais si elle est publique cela veut dire qu'elle a une précondition plus faible que le parent et donc qu'elle respecte le LSP ?

    Si tu as une classe mère avec une méthode publique, les classes filles qui en héritent doivent aussi avoir cette méthode qui soit publique (par héritage ou override) : tu ne peux pas "masquer" la méthode en changeant sa visibilité dans la classe fille.
    A oui en général j'ai rarement fait cela en pratique.

    Par nouvelle exception, c'est l'introduction d'une exception vérifiée (qui étend Exception et non RuntimeException donc) dans une méthode de l'enfant qui serait absente du parent.
    Je reviens à ceci afin de bien comprendre en réfléchissant un peu mieux sur le sujet , nous parlons bien dans le cas de l'override ? mais nous pouvons avoir une méthode de l'enfant avec une exception vérifiée qui cette méthode n'existe pas dans la super classe et ça respecte le LSP ?

    Non, en java ce n'est pas possible, dans d'autres langages peut-être, mais c'est un exemple de ce qui pourrait être une précondition plus forte dans la sous classe, à savoir qu'il est plus restrictif d'utiliser la méthode que dans le parent.

    Le LSP est agnostique du langage, mais c'était un mauvais exemple dans ce cas.
    D'accord j'avoue que c'est nouveau pour moi le LSP auriez-vous des liens , cours avec des exemples à l'appuis ?

Discussions similaires

  1. Problème avec le Liskov Substitution Principle
    Par amateur87 dans le forum C++
    Réponses: 4
    Dernier message: 05/10/2013, 11h55
  2. Redéfinition de méthode et principe de Liskov
    Par Ekinoks dans le forum C++
    Réponses: 68
    Dernier message: 05/02/2009, 18h04
  3. Réponses: 78
    Dernier message: 23/11/2008, 16h51
  4. [langage] substitution chaine
    Par sati dans le forum Langage
    Réponses: 4
    Dernier message: 11/12/2002, 10h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo