Partage
  • Partager sur Facebook
  • Partager sur Twitter

Polymorphisme et étendre l'interface

    19 avril 2018 à 13:33:01

    Bonjour,

    je me pose une question sur le polymorphisme. Si je comprends bien, ça permet de faire évoluer son programme en redéfinissant des fonctions dans des classes dérivées sans avoir à modifier les classes de base. Mais si j'ajoute des fonctions publiques aux classes dérivées, alors je ne peux plus utiliser mes objets dérivées comme la classe de base. Donc si j'étends les possibilités de ma classe, ça me permet de réutiliser du code déjà écrit, mais je dois dire au revoir au polymorphisme ?

    J'ai écrit peu de code orienté objet, et j'ai du mal à voir comment ça se passe en pratique.

    -
    Edité par èmji 19 avril 2018 à 16:38:08

    • Partager sur Facebook
    • Partager sur Twitter
      19 avril 2018 à 14:05:47

      Cela veut juste dire que tu peux employer tes objet de la classe enfant dans des fonctions qui manipulent des objets officiellement de la classe parente.

      Il est est évident que que tu ne peux pas demander d'appeler des choses qui n'existent pas dans l'interface parente.

      A toi de bien factoriser les comportements dans tes hiérarchies.

      • Partager sur Facebook
      • Partager sur Twitter
      C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
        19 avril 2018 à 14:25:18

        Ca depend de comment tu accèdes à tes nouvelles fonctions publiques. Le mieux serait probablement que tu lises un cours de conception objet, par exemple le livre de koala01 ou le blog d'Emmanuel deloget. Regardes en particulier les principes SOLID. (Surtout le "L" = principe de Liskov).

        Pour résumer, si tu as une fonction qui reçoit un objet polymorphique, le code doit rester valide quelque soit le type concret de l'objet. (Substituabilité). Avoir des fonctions spécifiques a une classe dérivée signifie que ton code n'est pas forcement substituable et donc moins maintenable, plus de risque de bugs, etc.

        Par contre, si tu as du code écrit spécifiquement pour la classe dérivée (donc du code qui n'utilise pas le polymorphisme), alors tu n'as pas de probleme de substituabilité.

        Un exemple concret avec Qt. Imagines que tu as un QEditText (pour éditer du texte) et un QLabel (pour afficher une image). Si tu veux ecrire un fonction polymorphique qui va mettre a jour le chemin, tu vas ecrire par exemple :

        void update(QWidget* widget, const QString& str) 
        {
            auto label = qobject_cast<QLabel*>(widget);
            if (label)
                label->setPixmap(QPixmap(str));
        
            auto textEdit = qobject_cast<QTextEdit*>(widget);
            if (textEdit)
                textEdit->setText(str);
        }

        Tu as une fonction polymorphique (ie qui peut recevoir plusieurs types d'objet, ici des QLabel ou des QTextEdit), mais qui utilise des fonctions spécifique de chaque classe qui ne sont pas dans la classe de base (QWidget).

        Tu vois que si tu veux ajouter une nouvelle classe, il faut modifier le code de "update". (Non respect du principe ouvert-fermé).

        Par contre, si tu crées une classe qui connait le type concret de ces objets, tu peux appeler directement les fonctions sans avoir de fonction polymorphique.

        class Window {
            QLabel* label;
            QTextEdit* textEdit;
        
            void update(const QString& str) 
            {
                label->setPixmap(QPixmap(str));
                textEdit->setText(str);
            }
        };

        Dans ce code, la fonction "update" n'est pas polymorphique (elle n'est pas appelé avec des parametres qui peuvent etre de types differents). Et pourtant, tes object "label" et "textEdit" sont des classes qui appartiennent a une hierarchie de classes.

        D'ailleurs, tu peux continuer a avoir des fonctions polymorphiques sur ces objets. Par exemple pour les deplacer avec la fonction "QWidget::move" :

        void moveWidget(QWidget* widget, int x, int y) 
        {
            widget->move(x, y);
        }
        
        moveWidget(label);
        moveWidget(textEdit);

        Dans ce code, label et textEdit sont encore des objets qui appartiennent a un heritage et la fonction "moveWidget" est polymorphique (recoit des QLabel et des QTextEdit) en respectant les principes SOLID.

        Donc pas de probleme pour avoir des fonctions publiques dans une classe derivée. Le polymorphisme est une propriete des fonctions, pas des classes. Pour avoir une conception correcte, il suffit juste de respecter certains principes.

        -
        Edité par gbdivers 19 avril 2018 à 14:27:22

        • Partager sur Facebook
        • Partager sur Twitter
          19 avril 2018 à 16:49:06

          Merci pour ses réponses simples et claires !

          • Partager sur Facebook
          • Partager sur Twitter

          Polymorphisme et étendre l'interface

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown