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 C++ Discussion :

Le changement de visibilité d'une fonction virtuelle est-il un viol du LSP ?


Sujet :

Langage C++

  1. #121
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    C'est bien le problème. Une classe, meme avec des methodes abstraites/virtuelles doit définir un comportement. Sinon ce n'est plus une conception d'objet, c'est juste une liste de signature de fonctions.
    Mais, comme une propriété, quand elle est associée à une fonction est "est capable de réagir à l'appel de la dite fonction", il est tout à fait logique de ne définir le comportement que lorsque l'on peut effectivement le faire.

    Non. On n'invoque pas un comportement. On invoque une méthode. Et le fait d'être en mesure d'invoquer une méthode ca ne valide rien du tout, a part que le code compile correctement.
    Là, je ne suis pas d'accord:

    C'est le fait de permettre d'invoquer un fonction donnée qui correspond (ou de faire, pourquoi pas, appel "à quelque chose d'accessible depuis l'extérieur d'un type donné") qui est une propriété valide:

    Tant que tu peux "faire appel à cette chose accessible depuis l'extérieur", la propriété associée est validée.

    Le fait que "cette chose accessible depuis l'extérieur" soit une fonction, que le comportement de cette fonction soit adapté (comprend: tout en restant cohérent avec ce que l'on attend du type réellement utilisé lorsque l'on appelle le dit comportement), ou que le résultat de ce comportement soit différent n'invalide absolument pas la propriété qui reste "d'être capable d'accéder" à ce qui est associé à cette propriété
    Le fait que l'implémentation de la méthode respecte le "contrat" du comportement de la classe, ça oui, ca valide le comportement.
    Dans un contexte donné qui est la programmation par contrat.

    Mais il n'est absolument pas question de ce contexte particulier dans l'énoncé de LSP: il te dit que, si tu peux faire appel à une propriété depuis l'objet de base, tu dois pouvoir faire appel à cette propriété depuis un objet dérivé.


    Je suis d'accord avec le fait que l'adaptation d'un comportement ou d'une propriété devrait respecter les invariants, mais cela n'intervient absolument pas dans LSP...

    Les deux seules choses que LSP impose sont:
    Que tu puisse invoquer un comportement du type de base au départ de n'importe quel objet de type dérivé
    Que le comportement invoqué reste "cohérent" par rapport à ce que l'on est en droit d'attendre (comprend: que addChild ne finisse pas par... retirer un objet, par exemple )
    Et ce que dit le LSP, c'est qu'un comportement existant ne doit pas être supprimé lors d'un héritage. On peut éventuellement ajouter ou enrichir les comportements, mais pas les supprimer.
    Enrichir ou adapter...

    Tout dépend du sens que tu donnes au terme "enrichir".

    En effet, dans le cadre de la programmation par contrat, tu peut être confronté au non respect des invariants, des pré et post conditions. Mais, comme je l'ai dit, cela n'a rien à voir avec LSP

    Par contre, je remarque avec plaisir que, pour en revenir au terme du débat, le fait de supprimer un comportement (en changeant l'accessibilité d'une fonction déclarée comme publique au niveau de la classe de base) viole effectivement LSP, vu que tu admets que l'on ne peut pas supprimer le dit comportement

    Le fait qu'en C++ (java, c#) on hérite automatique des méthodes publiques, ca implique alors que les méthodes publiques ne doivent être utilisées uniquement que pour décrire des comportements. C'est d'ailleurs une bonne pratique en Java/C# de passer par la définition d'interface pour spécifier des comportements et de les faire hériter à la classe.
    A condition que tu dispose, au niveau de l'interface, des données qui te permettent de fournir l'implémentation cohérente du résultat.

    En C++, la notion d'interface n'existe pas "en tant que telle", et on remarque qu'il n'y a pas vraiment de différence au niveau de la conception entre la création d'une interface et celle d'une fonction.

    De plus, java indique bel et bien le fait que l'utilisation d'une interface n'est pas un héritage vu qu'il utilise le mot clé "implements":

    La notion de ce mot clé est beaucoup plus proche de la relation "est implémenté en terme de" que de la relation "est un objet pouvant passer pour" (la fameuse relation EST-un )
    Mais comme je l'ai dit, tout cela n'a de sens que si on reste dans un model de conception orienté objet.
    Comme je l'ai dit, il n'y a pas de sens à vouloir appliquer un principe théorique spécifique à la conception objet en dehors d'un contexte objet
    Si on utilise le "mécanisme" d'héritage pour ce qui est somme toute du templating ou de la réutilisation de code, tout cela ne s'applique pas.
    L'héritage dans le but de réutilisation de code n'a pas *forcément* de sens au niveau LSP et est, généralement, déconseillé...

    Je te rappelle que tu n'a pas forcément de relation de hiérarchie entre du spécialisations données d'une seule et même classe template
    Et ton exemple de base/node/leaf entre a mon sens dans cette catégorie.
    Absolument pas: on entre dans le cadre du respect de LSP car, pour tout sous type de Base, il est possible d'invoquer la fonction addChild indépendamment du type réellement utilisé.

    De plus, tu remarquera qu'il n'y a strictement aucune récupération de code, même si j'aurais effectivement pu écrire le code sous la forme de
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    class Base
    {
        public:
            virtual Base() = 0; /* il faut bien interdire la création d'une instance
                                 * de Base ;)
                                 */
             virtual void addChild(Base*){throw CantHaveChildren();}
    };
    class Leaf : public Base
    {
        /* tous les comportements définis dans base sont exatement ceux
         * que l'on peut attendre pour une instance de Leaf
         */
    };
    class Node : public Base
    {
        public:
           /* adaptation du comportement à un type qui peut, effectivement,
            * disposer d'enfants
            */
            virtual void addChid(Base * b)
            {
                children_.push_back(b);
            }
        private:
            std::vector<Base*> children_;
    };
    Mais la différence n'apparait au final qu'au niveau de l'implémentation de ce que aura conçu "par ailleurs"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  2. #122
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Mais, comme une propriété, quand elle est associée à une fonction est "est capable de réagir à l'appel de la dite fonction", il est tout à fait logique de ne définir le comportement que lorsque l'on peut effectivement le faire.
    "être capable de réagir à l'appel de la dite fonction" n'est pas une propriété au sens comportemental du terme.

    Le LSP ne se limite pas au fait qu'il soit "possible d'appeler une fonction donnée", mais au fait qu'il est "obligatoire que la fonction ait le meme comportement".

    Bref, il ne suffit pas que le code compile pour que le LSP soit satisfait.

    C'est une extension de la question posée dans le PO : "est-ce que, du moment qu'on hérite et que ca compile, on respecte le LSP ?". Réponse : non.

    Citation Envoyé par koala01 Voir le message
    Absolument pas: on entre dans le cadre du respect de LSP car, pour tout sous type de Base, il est possible d'invoquer la fonction addChild indépendamment du type réellement utilisé.
    Idem. "Pouvoir invoquer la fonction addChild" n'est pas une propriété au sens comportemental du terme.

    La méthode "Base::addChild" décrit le fait de pouvoir ajouter un fils.

    Toute classe héritant de "Base" doit avoir une méthode permettant d'ajouter un fils. Hors la classe Leaf ne le permet pas.

    Mais comme je le disais, le problème de ton exemple va plus loin que le non respect du LSP. C'est une violation du principe objet.

    Une classe définit les caractéristiques et le comportement d'un objet.

    Hors de ton propre aveux, la classe Base ne définit pas de comportement. Ce qui fait qu'on n'est plus dans les principes de la programmation orienté objet, et donc la discussion sur le LSP devient caduque.

    Le fait est que la classe Leaf ne doit pas définir la possibilité d'ajouter un fils. Hors toi, tu définis cette possibilité (existence de la méthode) tout en choisissant une implémentation qui à pour résultat de ne jamais créer de fils.

    Mais on pourrait tout de meme créer une classe héritant de Leaf et ayant une implémentation permettant l'ajout de fils. Et ainsi de suite. Ce qui rendrait la notion d'héritage objet nettement moins pratique.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  3. #123
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Pseudocode, en lisant ton argumentaire j'ai l'impression que tu ne fais qu'exploiter le manque de définition de chaque mot employé dans cette discussion.

    A ce que je sache, le comportement dont parle koala est simplement les possibilités, les actions/propriétés/services qu'expose l'objet ou son type, et bien juste l'existence de ces possibilités, pas leur effet/implémentation/tu m'as compris.

    Or si le LSP ne désigne pas justement précisément ce comportement, ces possibilités, ce contrat.... alors toute la notion d'héritage tel qu'on la pratique dans les différents language objets n'entrerait pas dans le cadre du LSP.

    Parceque le principe de base de l'héritage, c'est justement que l'effet, l'implémentation, la définition du service est dépendant du type enfant, pas de ses parents.
    Ses parents ne fournissent qu'une base d'implémentation sur laquelle s'appuyer, ou pas, pour fournir la version spécifique.


    Maintenant, je pense que la discussion serait plus saine avec quelques définitions des termes employés, parceque vous utilisez tous des mots semblables pour des choses différentes.

  4. #124
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Klaim Voir le message
    Pseudocode, en lisant ton argumentaire j'ai l'impression que tu ne fais qu'exploiter le manque de définition de chaque mot employé dans cette discussion.

    A ce que je sache, le comportement dont parle koala est simplement les possibilités, les actions/propriétés/services qu'expose l'objet ou son type, et bien juste l'existence de ces possibilités, pas leur effet/implémentation/tu m'as compris.

    Or si le LSP ne désigne pas justement précisément ce comportement, ces possibilités, ce contrat.... alors toute la notion d'héritage tel qu'on la pratique dans les différents language objets n'entrerait pas dans le cadre du LSP.

    Parceque le principe de base de l'héritage, c'est justement que l'effet, l'implémentation, la définition du service est dépendant du type enfant, pas de ses parents.
    Ses parents ne fournissent qu'une base d'implémentation sur laquelle s'appuyer, ou pas, pour fournir la version spécifique.


    Maintenant, je pense que la discussion serait plus saine avec quelques définitions des termes employés, parceque vous utilisez tous des mots semblables pour des choses différentes.
    Tout à fait...

    Je vais donc recommencer par mes définitions qui sont, me semblent-ils, cohérentes avec l'approche orientée objet de manière générale:

    Je tiens d'abord à fixer ici que l'on parle de l'héritage publique au sens orienté objets du terme à visées de polymorphisme d'inclusion, c'est à dire de la relation que l'on qualifie généralement de relation "EST-UN".

    Une classe est une variable capable de fournir certains comportements, de répondre ou d'émettre (à) certains messages.

    Une propriété de type: C'est la capacité (ou non) de faire appel à "une partie spécifique" du type. Cette partie spécifique peut être un membre de la classe ou une fonction membre de celle-ci.

    Pour ce qui est des fonctions associées aux différentes propriétés, on ne s'intéresse qu'à leur signature, indépendamment du comportement qu'elles auront.

    De prime abord, les fonctions libres ne sont que rarement considérables comme des propriétés de types, bien que l'on puisse envisager des exceptions, comme, par exemple, lesfonctions que l'on pourrait régulièrement garder sous la forme de fonctions membres mais que l'on "sort" du type envisagé en déclarant une relation d'amitié avec celui-ci.

    On se rend compte ici que la fameuse fonction typeid n'a strictement rien à voir avec LSP, car ce n'est pas une propriété des types qui lui sont passés

    Le comportement: c'est la suite logique d'instructions effectuées par la fonction que l'on observe.

    Le résultat est peut être ce qui regroupe le plus de chose. C'est: ce que l'on obtient après avoir exécuté le comportement de manière "atomique", les valeurs / données éventuellement récupérées en fin de comportement, que ce soit par valeurs de retours ou par variables transmises comme paramètres et modifiées par le comportement observé.

    Une fois ceci posé, Klaim a très justement rappelé que le propre de l'approche objet est de permettre l'adaptation des comportements des types dérivés par rapport au types dont ils héritent.

    J'en profite pour rappeler que, lorsque l'on utilise une instance de type dérivé comme étant une instance de son type de base, on ne peut manipuler cette instance depuis la fonction dans laquelle cette substitution est faite qu'au travers de l'interface publique du type de base.

    Or, on s'attend, en manipulant l'interface publique du type de base, à ce que la réaction corresponde au type réellement manipulé.

    Il n'y aurait donc pas la moindre logique à refuser l'adaptation du comportement associé à une propriété, simplement, parce que cela interdirait toute forme de polymorphisme, car, le polymorphisme est justement un des piliers de la programmation objets.

    Ce que dit LSP, c'est que si le type "de base" dispose d'une propriété valide(comprend: donne la capacité de faire appel à une fonction donnée), les sous types (les types dérivés) doivent aussi disposer de cette propriété valide (comprenez: ils doivent aussi permettre de faire appel à la fonction envisagée).

    LSP ne donne aucune indication sur "ce qui est acceptable" comme modification du comportement de la fonction associée à la propriété ni (et encore moins!!!) sur une quelconque obligation d'obtenir un résultat identique: il ne s'intéresse qu'à ce que j'ai appelé les propriétés de types.

    Simplement:

    il faut effectivement, bien que cela n'ait plus rien à voir avec LSP, que le comportement reste cohérent. Comprenez par là qu'une fonction qui serait sensée tenter de rajouter un enfant à un objet ne doit pas en arriver... à essayer d'en retirer un du fait de l'adaptation du comportement dans un type dériver. Décider de ne pas rajouter l'enfant et de lancer une exception parce que le type dérivé (réellement manipulé) ne peut pas avoir d'enfant reste cependant un comportement cohérent, qu'il est normal d'admettre pour le type dérivé qui est dans la situation.

    Ensuite, il y a le cas de la programmation par contrats, qui n'est jamais qu'une manière particulière d'envisager la programmation objets.

    Dans ce cas particuliers, il faut, effectivement, veiller à ce que les types dérivés respectent également le ou les contrat(s) du type de base, mais cela n'a pas non plus le moindre rapport avec LSP.

    Pour (écrire mon roman ) terminer ma synthèse je reviendrai rapidement sur le problème de la prise en compte du langage utilisé (parce que l'on remarque effectivement que C++ nous autorise à nous poser des questions ici ), afin de répéter ma thèse concernant la question d'origine:

    Je rappellerai donc que LSP est un principe de conception, qu'il ne sert à rien de vouloir le placer dans un contexte plus important que celui du "on connait les besoins à rencontrer, on connait les classes principales dont on aura besoin, et on réfléchi aux relations qui peuvent exister entre elles".

    Comme je l'ai signalé naguère, on pourrait, réfléchir à son respect alors que "celui qui décide" n'a pas encore choisi le langage dans lequel l'application sera implémentée.

    Il ne sert qu'à répondre à la question "puis-je envisager de faire hériter telle classe de telle autre?".

    Une réponse négative à cette question (sous l'aspect de LSP) interdira définitivement l'héritage, y compris si, pour une raison quelconque, le langage venait à accepter que l'on y ait recours.

    Ce n'est qu'après avoir obtenu cette réponse que la notion de langage interviendra pour, éventuellement, apporter de nouvelles restrictions (en nous faisant observer que "mince, c'est vrai.... la classe Machin hérite déjà de la classe Bidule, et le langage Brol n'autorise pas l'héritage multiple" ).

    En cela, et comme toute propriété valide pour le type de base se doit d'être valide (même si le comportement associé est adapté) pour le type dérivé, le fait d'imposer une restriction à l'accessibilité d'une fonction publique (comprenez: la faire passer en accessibilité protégée ou privée dans un ou des types dérivés) doit être considérée comme violant LSP.

    Par contre, le fait de retirer des restrictions (comprenez: le fait de faire passer une fonction privée ou protégée dans l'accessibilité publique) n'est pas à considérer comme un viol de LSP, du seul point de vue de la conception du moins.

    Il faut cependant admettre qu'une telle situation n'est absolument pas saine.

    On peut en effet estimer que l'on (l'équipe de conception / développement) a décidé de restreindre l'accès à une fonction donnée, c'est sans doute que l'on avait de bonnes raisons pour le faire.

    Il sera dés lors difficile de trouver un justification plausible et cohérente au fait de lever la restriction, mais, toutes situation étant par nature unique, il n'est pas impossible qu'une telle justification puisse arriver de manière plus ou moins exceptionnelle.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #125
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Klaim Voir le message
    Pseudocode, en lisant ton argumentaire j'ai l'impression que tu ne fais qu'exploiter le manque de définition de chaque mot employé dans cette discussion.

    A ce que je sache, le comportement dont parle koala est simplement les possibilités, les actions/propriétés/services qu'expose l'objet ou son type, et bien juste l'existence de ces possibilités, pas leur effet/implémentation/tu m'as compris.

    Or si le LSP ne désigne pas justement précisément ce comportement, ces possibilités, ce contrat.... alors toute la notion d'héritage tel qu'on la pratique dans les différents language objets n'entrerait pas dans le cadre du LSP.

    Parceque le principe de base de l'héritage, c'est justement que l'effet, l'implémentation, la définition du service est dépendant du type enfant, pas de ses parents.
    Ses parents ne fournissent qu'une base d'implémentation sur laquelle s'appuyer, ou pas, pour fournir la version spécifique.


    Maintenant, je pense que la discussion serait plus saine avec quelques définitions des termes employés, parceque vous utilisez tous des mots semblables pour des choses différentes.
    A l'inverse, moi j'ai l'impression que vous redéfinissez le sens des termes communément utilisés en objet pour coller avec les possibilités offertes par le langage.

    Quand le parle de communément utilisé je parle par exemple des définitions de wikipedia, qui bien que discutables n'en demeurent pas moins une synthèse du sens commun.

    Object-oriented programming , Class, Liskov substitution principle, ...

    A class is a model of a concept within a computer program. Fundamentally, it encapsulates the state and behavior of the concept it represents. It encapsulates state through data placeholders called attributes (or member variables or instance variables); it encapsulates behavior through reusable sections of code called methods.
    Inheritance is a process in which a class inherits all the state and behavior of another class.
    More formally, the Liskov substitution principle (LSP) is a particular definition of a subtyping relation, called (strong) behavioral subtyping
    Bien sur, vous êtes libres d'utiliser une définition du concept "objet" basée sur les types plutot que sur les comportements. Mais je trouve que c'est un choix un peu biaisé par l'utilisation du langage (C++, java, ...), car ce langage impose une déclaration/utilisaton rigoureuse des types de données alors qu'il laisse une totale liberté sur le comportement devant être implémenté.

    Je pense meme que la raison d'exister du LSP est de forcer le développeur à se rappeler que le "comportement" est aussi important que le "type".

    Voila, c'est ma vision des choses, orientée conception plus qu'implémentation. Je pense que cette vision est aussi cohérente que la votre, et elle a le mérite de me simplifier la vie.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  6. #126
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Une propriété de type: C'est la capacité (ou non) de faire appel à "une partie spécifique" du type. Cette partie spécifique peut être un membre de la classe ou une fonction membre de celle-ci.
    J'arrive pas à avoir accés au document rédigé par Liskov et Wing où elles définisent le LSP de manière formel. Mais j'ai toujours compris propriété au sens mathématique du terme, et pas avec une autre définition (si tu as une référence je sus preneur).

    D'après ce que tu dis, si je définie la propriété P comme P(x) : "x peut recevoir le message foo et sa <<réponse>> est A" (A un élément fixé d'un type fixé, x T-objet, <<message>> n'est peut-etre pas le terme exact, je me souvient plus de la terminologie objet pour désigner le retour d'un message). Alors cette prorpiété n'a pas à intervenir dans le LSP, et donc on peut envisager qu'un y S-objet avec S sous-type de T ne respecte pas la seconde partie de la prorpriété (la première partie est aussi respecté d'après ce que tu dis), donc la réponse au message foo d'un T-objet peut être B!=A.

    Or si je me trompe pas ceci viole directement une conséquence directe du LSP qui est que les post-condition ne peuvent être plus faible, ce qui est le cas si l'ensemble des valeur de retour du message se trouve augmenté. (fait partie de la formulation équivalente au LSP dans le cas de la programmation par contrat si je me trompe pas)

    Pour le fait que le langage ne doit pas intervenir, je suis d'accord, et c'est même cette argument là qui vient, en premier, AMA, pour invalider le raisonnement sur le typeid, qui abstrait du langage comme je l'ai fait ne viole pas le LSP (quelque soit le sens du mots propriété).

  7. #127
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    J'arrive pas à avoir accés au document rédigé par Liskov et Wing où elles définisent le LSP de manière formel. Mais j'ai toujours compris propriété au sens mathématique du terme, et pas avec une autre définition (si tu as une référence je sus preneur).
    En fait, quel que soit le domaine d'application que tu envisage, une propriété représente toujours quelque chose d'intrinsèque à la chose que tu étudie.

    Je vais prendre l'exemple d'un domaine que je connais relativement bien: le domaine de la connaissance des matériaux de construction.

    Mettons que tu aies une pièce de bois, une pièce d'aluminimum, une pièce de fonte et une pièce de PVC les unes à coté des autres. Toutes les pièces ont, pour les besoins de la cause, les même dimensions et sont considérées comme étant en matière pure.

    Les propriétés marquantes de ces matériaux, par exemple:
    • la conductivité électrique
    • la conductivité calorique
    • la résistance à la pression
    • la dureté
    • la résistance à la traction
    • (pourquoi pas) le coefficient d'élongation
    • la résistance à la flexion
    • le poids volumique
    • j'en passe et de meilleures
    Il existe, pour chacune de ces propriété un appareil qui permet de l'évaluer, ainsi qu'une manière de la représenter, et il est potentiellement possible de "trier" les différents matériaux en fonction d'une (ou de plusieurs) de ces propriétés.

    De même, nous pourrions dire, en mathématique, que le fait d'être pair ou impair est une propriété de tout nombre entier, parce que c'est, encore une fois, intrinsèque au nombre entier que l'on étudie.

    C'est pour cela que j'attirais l'attention sur le fait qu'une fonction libre ne peut a priori pas être considérée comme une propriété: Toute propriété fait indéniablement partie de ce que l'on pourrait appeler "l'essence même" de ce que l'on étudie.

    LSP nous parle de propriétés "valides", c'est à dire d'éléments que l'on peut utiliser.

    Or, quand on est "en dehors" d'un objet ou d'un type, la seule chose que l'on puisse envisager d'utiliser tient dans... son interface publique.
    D'après ce que tu dis, si je définie la propriété P comme P(x) : "x peut recevoir le message foo et sa <<réponse>> est A" (A un élément fixé d'un type fixé, x T-objet, <<message>> n'est peut-etre pas le terme exact, je me souvient plus de la terminologie objet pour désigner le retour d'un message). Alors cette prorpiété n'a pas à intervenir dans le LSP, et donc on peut envisager qu'un y S-objet avec S sous-type de T ne respecte pas la seconde partie de la prorpriété (la première partie est aussi respecté d'après ce que tu dis), donc la réponse au message foo d'un T-objet peut être B!=A.
    Ce que je dis c'est qu'une propriété est la capacité que l'on a d'accéder, depuis l'extérieur de l'objet ou du type à une donnée ou à une fonction proposée par l'objet ou le type.

    Je dis que LSP ne s'intéresse qu'à cette capacité que l'on a d'accéder à certaines informations (données ou fonctions membres) de l'objet ou du type envisagé.

    Je dis enfin que LSP n'impose et n'interdit absolument rien quant à la manière dont les fonctions seront réellement exécutées: Ce qui importe, c'est de pouvoir les appeler.

    Evidemment, il s'agira de veiller à ce que l'exécution des fonctions reste cohérente pour tout type et tout objet dérivé. Mais LSP n'en parle absolument pas

    En gros, tu peux te dire que tout élément intervenant dans ce que l'on appelle "l'interface publique" d'un type ou d'un objet est associé à une propriété (différente à chaque fois) "donne accès à...".

    Et bien sur, je dis qu'il n'y a que ce qui est intrinsèque à l'objet ou au type étudié qui puisse servir de propriété.

    Il est vrai qu'en math, nous écririons la propriété P de X sous la forme de P(X), mais, en programmation l'écriture sera beaucoup plus proche de X.P (le point représentant ici le fait d'accéder à quelque chose qui fait partie intégrante de X )

    En effet, la notation mathématique tend à laisser envisager le fait que n'importe quelle fonction libre utilisant un X comme paramètre pourrait être utilisée comme propriété.

    Or, les fonctions libres ne faisant, par définition, pas partie intégrante des objets ou des types, elles ne peuvent, a priori, pas être considérées comme des propriétés.

    Je me demande d'ailleurs si ce n'est pas, justement, cette notation mathématique "trompeuse" qui a incité white_tentacle à estimer que typeid pouvait être considéré comme une propriété
    Or si je me trompe pas ceci viole directement une conséquence directe du LSP qui est que les post-condition ne peuvent être plus faible, ce qui est le cas si l'ensemble des valeur de retour du message se trouve augmenté. (fait partie de la formulation équivalente au LSP dans le cas de la programmation par contrat si je me trompe pas)
    Non...

    LSP ne s'intéresse absolument pas en particulier à la programmation par contrat:

    Tu peux respecter LSP sans respecter les règles de la programmation par contrat, car rien ne t'oblige à l'utiliser.

    Par contre, si tu envisages d'utiliser la programmation par contrat, tu ne pourra pas décider de faire hériter une classe d'une autre, même si les règles concernant les pré-condtions, les post-conditions et les invariants sont respectées si... LSP n'est pas respecté à la base.

    On se retrouve, lorsqu'on programme par contrat, exactement dans la même situation que celle que l'on a déjà abordée en long en large et en travers de l'interdiction par un langage d'avoir recours à l'héritage multiple.

    LSP va juste te dire si tu peux (ou non) envisager d'avoir un héritage.

    Et, pour cela, il faut que l'interface publique (tout confondu) du type dérivé propose au minimum à l'utilisateur l'ensemble de ce que propose l'interface publique du type de base.

    Je parle, bien sur uniquement de ce que LSP impose, car, au delà (et avant même de t'intéresser aux restrictions de langage ou de système de programmation utilisé), il s'agira de veiller à ce qu'il soit "sémantiquement opportun" d'envisager l'héritage.

    Je veux dire par là que, même s'il dispose d'une interface strictement semblable, il ne faut normalement pas envisager l'héritage si tu ne peux pas décemment dire "en toute bonne foi" qu'un objet du type dérivé EST UN objet du type de base:

    Faire hériter (même s'il y avait une interface commune) Vehicule de Arbre n'aurait par exemple aucun sens, parce qu'on ne peut décemment pas dire en toute bonne foi qu'un véhicule est un arbre (ce qui n'empêche pas forcément que ces deux types puissent avoir un ancêtre commun... C'est ce que l'on remarque avec la classe Object de java )

    En gros, il y a quatre questions qui méritent d'être posées quand on envisage le recours à l'héritage. Dans l'ordre:
    1. Est-il sémantiquement opportun de faire hériter X de Y (cf quelques lignes plus haut )
    2. LSP est-il respecté avec l'héritage
    3. Quelles restrictions le langage pourrait apporter à l'héritage
    4. Quelles sont les restrictions qui pourraient être induites par mon "style de programmation" (ex: programmation par contrat)

    C'est ainsi que l'on pourrait parfaitement envisager d'avoir trois classes (que je nommerai X, Y et Z), de constater que Y présente exactement l'interface de X + une ou deux fonctions qui lui sont propres et que Z présente exactement l'interface de Y + une ou deux fonctions qui lui sont propres sans qu'il n'y ait la moindre relation d'héritage entre ces trois classes, simplement parce que l'on ne peut pas décemment estimer du point de vue sémantique qu'un Y EST-UN X ni qu'un Z EST-UN Y.
    Pour le fait que le langage ne doit pas intervenir, je suis d'accord, et c'est même cette argument là qui vient, en premier, AMA, pour invalider le raisonnement sur le typeid, qui abstrait du langage comme je l'ai fait ne viole pas le LSP (quelque soit le sens du mots propriété).
    Si, pour une raison ou une autre, tu arrive sur un "non à l'héritage", il ne servira strictement à rien de se poser les questions suivantes, car l'héritage obtenu deviendrait tout à fait artificiel et le résultat serait de te préparer des catastrophes.

    Il y a, en définitive, deux raisons valables pour invalider le raisonnement que suivait white_tentacle sur typeid:
    • Le fait que le langage n'intervient absolument pas lorsqu'il s'agit d'évaluer le respect de LSP
    • Le fait que typeid est une fonction qui n'est absolument pas appelée à partir d'un type ou d'un objet, mais que c'est une fonction à laquelle on passe un type ou un objet.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #128
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    LSP ne s'intéresse absolument pas en particulier à la programmation par contrat:

    Tu peux respecter LSP sans respecter les règles de la programmation par contrat, car rien ne t'oblige à l'utiliser.


    C'est bien la première fois que j'entends défendre ça...

    http://en.wikipedia.org/wiki/Liskov_...tion_principle

    In the same paper, Liskov and Wing detailed their notion of behavioral subtyping in an extension of Hoare logic, which bears a certain resemblance with Bertrand Meyer's Design by Contract in that it considers the interaction of subtyping with pre- and postconditions.
    Et la page en français est tout aussi explicite :

    http://fr.wikipedia.org/wiki/Princip...tion_de_Liskovhttp://fr.wikipedia.org/wiki/Princip...tion_de_Liskov

    Et pour repartir sur la définition :

    Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.
    Il n'y a pas de limite à q. Ca peut être n'importe quoi (et notamment, typeid et Liskov ne font pas bon ménage, ce qui est cohérent, alors qu'instanceof (comme en C#, par exemple), ne pose pas de problème).

  9. #129
    Membre éclairé Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Points : 845
    Points
    845
    Par défaut
    En raisonnant sur les définitions du LSP, on peut en effet violer le principe avec une construction choisie à base de typeid. Mais je dirai que ça n'a que peu d'intérêt dans le sens où on peut sans difficulté sélectionner un "property" (ou proposition) qui ne serait pas corrélé à un invariant. Comme la différence de comportement est ce qui est recherché lorsque l'on fait du polymorphisme, cela n'apporte pas grand chose: on viole LSP pour un property q.

    koala01, j'ai l'impression que tu argumentes sur le fait que "property", tel que mentionné dans la def de LSP, se comprend comme "élément" de l'interface d'un objet (membre ou fonction membre). En fait, le property est juste une "proposition" que l'on peut décider comme vraie ou fausse. Ca reste très général et peu contraignant (d'ailleurs on parle de principe de LSP, et non pas de lemme ou que sais-je encore!)

  10. #130
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par metagoto Voir le message
    koala01, j'ai l'impression que tu argumentes sur le fait que "property", tel que mentionné dans la def de LSP, se comprend comme "élément" de l'interface d'un objet (membre ou fonction membre). En fait, le property est juste une "proposition" que l'on peut décider comme vraie ou fausse. Ca reste très général et peu contraignant (d'ailleurs on parle de principe de LSP, et non pas de lemme ou que sais-je encore!)
    +1. D'ailleurs c'est ce que koala01 décrit dans la première partie de son post (les propriétés marquantes des matériaux). C'est dans la seconde partie, lorsqu'il pose sa propre définition ("une propriété est la capacité que l'on a d'accéder...") que je ne suis plus d'accord avec lui.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  11. #131
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par white_tentacle Voir le message


    C'est bien la première fois que j'entends défendre ça...
    +1/
    Il me semble même que dans l'article les termes pré-conditions/post-conditions apparaissent explicitement pour préciser ce qu'est le comportement d'une fonction.

  12. #132
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par white_tentacle Voir le message


    C'est bien la première fois que j'entends défendre ça...

    http://en.wikipedia.org/wiki/Liskov_...tion_principle



    Et la page en français est tout aussi explicite :

    http://fr.wikipedia.org/wiki/Princip...tion_de_Liskovhttp://fr.wikipedia.org/wiki/Princip...tion_de_Liskov
    In the same paper, Liskov and Wing detailed their notion of behavioral subtyping in an extension of Hoare logic, which bears a certain resemblance with Bertrand Meyer's Design by Contract in that it considers the interaction of subtyping with pre- and postconditions.
    Montre moi les termes "programmation by contract","preconditions" ou "postconditions" dans la phrase que tu cite...

    Et pour repartir sur la définition :
    Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.
    On te parle de propriété prouvable, de type, de sous type, d'objets, mais absolument pas de programmation par contrat.

    Le fait que le principe ait été énoncé à l'occasion d'un papier sur la programmation par contrat ne veut absolument pas dire qu'il ne soit applicable qu'à ce type de programmation!!!

    Comprenons nous: je ne remets absolument pas en cause l'intérêt de la programmation par contrat, mais je dis juste qu'elle n'est pas toujours applicable, et donc pas forcément appliquée.

    Ce qui n'empêche que le principe puisse (doive) aussi être appliqué lorsque l'on est en dehors du cas de la programmation par contrat.
    Il n'y a pas de limite à q. Ca peut être n'importe quoi (et notamment, typeid et Liskov ne font pas bon ménage, ce qui est cohérent, alors qu'instanceof (comme en C#, par exemple), ne pose pas de problème).
    Ce doit quand même être une propriété valide.

    Or, une propriété est intrinsèque par nature: c'est quelque chose qui s'applique au départ du type ou de l'objet envisagé, et non qui reçoit le type ou l'objet envisagé en paramètre.
    Citation Envoyé par metagoto Voir le message
    En raisonnant sur les définitions du LSP, on peut en effet violer le principe avec une construction choisie à base de typeid. Mais je dirai que ça n'a que peu d'intérêt dans le sens où on peut sans difficulté sélectionner un "property" (ou proposition) qui ne serait pas corrélé à un invariant. Comme la différence de comportement est ce qui est recherché lorsque l'on fait du polymorphisme, cela n'apporte pas grand chose: on viole LSP pour un property q.

    koala01, j'ai l'impression que tu argumentes sur le fait que "property", tel que mentionné dans la def de LSP, se comprend comme "élément" de l'interface d'un objet (membre ou fonction membre).
    J'argumente effectivement en ce sens, mais
    En fait, le property est juste une "proposition" que l'on peut décider comme vraie ou fausse.
    Non, ce n'est pas une proposition, et non on ne peut pas décider si elle est vrai ou fausse: on parle de propriété prouvable ou de propriété valide.

    On ne peut donc pas décider de valider la propriété ou non, de la prouver ou non: la validation est faite (ou non), la preuve est faite (ou non), on... fait avec et on en tire les conséquences.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  13. #133
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    koala01> Dans la citation ya bien les mots dits, mais :

    which bears a certain resemblance with Bertrand Meyer's Design by Contract in that it considers the interaction of subtyping with pre- and postconditions.
    Donc ce ne sont que des ressemblances, pas directement liés.

  14. #134
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Klaim Voir le message
    koala01> Dans la citation ya bien les mots dits, mais :

    Donc ce ne sont que des ressemblances, pas directement liés.
    Attention, tu trouve le terme "desing by contract" dans le texte de wikipedia, mais tu n le trouve pas dans l'énoncé du principe.

    L'auteur du texte du wiki a donc sacrifié le ton de l'explication au profit du ton de l'analyse, et je ne suis pas forcément en accord avec ce qui est dit. (j'irais d'ailleurs plus loin en disant que l'auteur du texte a fait une erreur en ajoutant cette remarque )

    EDIT: par contre, je constate avec plaisir que tu admets explicitement que ce n'est pas directement lié.

    La conclusion qui s'impose est donc que tu peux appliquer LSP sans pour autant appliquer les règles imposée par la programmation par contrat.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  15. #135
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    +1/
    Il me semble même que dans l'article les termes pré-conditions/post-conditions apparaissent explicitement pour préciser ce qu'est le comportement d'une fonction.
    Effectivement, l'énoncé du principe est apparue à l'occasion d'un papier portant sur la programmation par contrat.

    Effectivement, Je ne peux pas nier que les motivations du papier indiquaient clairement la nécessité de fournir les moyens de s'assurer du respects des règles de ce style de programmation.

    Mais il n'empêche que la notion d'héritage est apparue bien avant que l'on se rende compte de l'intérêt de la programmation par contrat, et que ce style de programmation n'est pas *forcément* appliqué ni applicable.

    Par contre, je te reporte à la définition d'un principe. c'est
    La base sur laquelle repose l'organisation de quelque chose, ou qui en régit le fonctionnement (sources: larousse.fr)
    Si l'on décide de transiger avec un principe, il ne faudra pas s'étonner si, au final, on se retrouve avec un "colosse aux pieds d'argile", avec des hiérarchies dont les bases ne sont pas cohérentes, voire risquées.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  16. #136
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    +1. D'ailleurs c'est ce que koala01 décrit dans la première partie de son post (les propriétés marquantes des matériaux). C'est dans la seconde partie, lorsqu'il pose sa propre définition ("une propriété est la capacité que l'on a d'accéder...") que je ne suis plus d'accord avec lui.
    Et pourtant, je ne fais que me reporter à la définition de la propriété que l'on trouve dans le dictionnaire, à savoir:
    Qualité propre de quelque chose qui le distingue d'autre chose ; particularité : Les propriétés physiques d'un corps.

    Droit d'user, de jouir et de disposer d'une chose d'une manière exclusive et absolue (sources: larousse.fr)
    Les propriétés d'un type sont donc les "informations" qui rendent ce type particulier, ce qui nous permet d'accéder aux informations qui sont potentiellement à l'usage exclusif du type ou de l'objet envisagé.

    Cela reprend donc tout ce qui se trouve... dans l'interface publique du type ou de l'objet envisagé
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  17. #137
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Si l'on décide de transiger avec un principe, il ne faudra pas s'étonner si, au final, on se retrouve avec un "colosse aux pieds d'argile", avec des hiérarchies dont les bases ne sont pas cohérentes, voire risquées.
    ? Cette remarque est plutôt surprenante de ta part, vu que tu sembles adopter le point de vue d'une "orientation objet" caractérisée par le "type" plutot que par le "comportement".

    Ce qui fait que tu sembles accepter qu'une classe "Carré" puisse hériter d'une classe "Rectangle" au motif que l'une est un cas particulier de l'autre (= une spécialisation du type). C'est cela ?
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  18. #138
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    ? Cette remarque est plutôt surprenante de ta part, vu que tu sembles adopter le point de vue d'une "orientation objet" caractérisée par le "type" plutot que par le "comportement".

    Ce qui fait que tu semble accepter qu'une classe "Carré" puisse hériter d'une classe "Rectangle" au motif que l'une est un cas particulier de l'autre (= une spécialisation du type). C'est cela ?
    Tu ne sembles pas avoir compris le sens de ma remarque car, justement, je dis que si on n'applique pas scrupuleusement le principe, c'est l'ensemble de la conception qui devient bancale.

    Je plaide en effet en faveur d'une conception caractérisée par le type, mais, surtout, d'une conception caractérisée par les propriétés que les différents types exposent, juste après avoir établi le fait que la sémantique nous autorise à envisager qu'un type dérivé puisse être considéré comme "étant du type de base".

    J'admets "simplement" que, à défaut d'être chef de ton équipe de dev, je n'ai pas vraiment d'ordre à te donner, mais je te lance un avertissement concernant les risques auxquels tu t'expose si tu décide, pour une raison ou une autre, de transiger dans la manière que l'on peut avoir de respecter les différents principes .
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  19. #139
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Tu ne sembles pas avoir compris le sens de ma remarque car, justement, je dis que si on n'applique pas scrupuleusement le principe, c'est l'ensemble de la conception qui devient bancale.

    Je plaide en effet en faveur d'une conception caractérisée par le type, mais, surtout, d'une conception caractérisée par les propriétés que les différents types exposent, juste après avoir établi le fait que la sémantique nous autorise à envisager qu'un type dérivé puisse être considéré comme "étant du type de base".
    ? Ca ne contredit pas ma remarque.

    - Un rectangle est un quadrilatère dont les quatre angles sont des angles droits.
    - Un carré possède les mêmes propriétés qu'un rectangle

    Tu sembles donc d'accord pour dire qu'on peut donc définir une classe "Carré" qui hérite de la classe "Rectangle". Non ?

    J'admets "simplement" que, à défaut d'être chef de ton équipe de dev, je n'ai pas vraiment d'ordre à te donner, mais je te lance un avertissement concernant les risques auxquels tu t'expose si tu décide, pour une raison ou une autre, de transiger dans la manière que l'on peut avoir de respecter les différents principes .
    La dessus, on est d'accord.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  20. #140
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Tu sembles donc d'accord pour dire qu'on peut donc définir une classe "Carré" qui hérite de la classe "Rectangle". Non ?
    Si elle est non mutable, ca ne me gene pas, si elle l'est, ca me gene vraisemblablement (ca va dependre des aspects mutables).

    (J'ai pas suivi du tout la conversation. Comme reponse a la question qui est le titre de cette discussion, passer a une accessabilite -- je suppose que visibilite est employe a mauvais escient, l'acception C++ du terme n'ayant aucun sens dans le contexte -- moins contraignante ne me gene pas, passer a une accessibilite plus contraignante bien. Savoir si c'est a cause du LSP ou d'autre chose, je m'en fous.)
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/10/2008, 16h37
  2. Fonction appelant une fonction virtuelle pure
    Par oodini dans le forum C++
    Réponses: 12
    Dernier message: 19/09/2008, 08h24
  3. Une fonction virtuelle ne peut pas retourner un template!
    Par coyotte507 dans le forum Langage
    Réponses: 10
    Dernier message: 08/02/2008, 20h39
  4. Problème de visibilité d'une fonction
    Par hello2lu dans le forum VBA Access
    Réponses: 8
    Dernier message: 03/07/2007, 15h20
  5. Réponses: 2
    Dernier message: 05/03/2006, 19h29

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