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

Langages de programmation Discussion :

Héritage classes carré/rectangle


Sujet :

Langages de programmation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut Héritage classes carré/rectangle
    Bonjour à tous,

    Lorsque j'étais étudiant, les profs qui m'ont enseigné l'objet (Java) m'ont sorti cet exemple de la classe carré qui hérite de la classe rectangle.
    Aujourd'hui, je tombe sur de plus en plus de discussions à ce sujet stipulant que c'est une aberration de conception.

    Ma question est alors simple: pourquoi?
    (avec un minimum d'explications SVP )

  2. #2
    Membre Expert

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Par défaut
    Aujourd'hui, je tombe sur de plus en plus de discussions à ce sujet stipulant que c'est une aberration de conception.
    Quoi donc ? Le carré qui dérive du rectangle ? Tu as des exemples ?

    Parce que pour moi, toujours l'exemple qu'on prend pour expliquer qu'il ne faut pas tomber dans le piège de l'héritage d'implémentation :
    - Normalement, un carré est un rectangle particulier, donc tu dois le faire dériver du rectangle.
    - L'héritage d'implémentation consiste à dire : J'ai des classes, je factorise les attributs communs dans une classe de base, puis je la spécialise pour ajouter les attributs manquants dans les classes dérivées.
    Si t'ammènes à dire : Pour modéliser un carré, je n'ai besoin que de la longueur, ou la largeur. Donc j'ai un seul attribut.
    Pour modéliser un rectangle, j'ai besoin d'une dimension de plus, donc je spécialise le carré pour lui ajouter la longueur qui me manque.
    Tu bâtis ainsi l'héritage uniquement à partir des attributs communs que tu factorises, sans qu'il y est nécessairement de lien sémantique entre les classes.

    Pour moi, c'est l'héritage d'implémentation qui est une abérration. Si ta hiérarchie de classe ne modélise pas un lien sémantique, ton modèle finira par tomber sur des contradictions qui vont tout casser...

  3. #3
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    comme dirais zaho c'est chelou !!!! En tout cas pour moi (concepteur pas mathématicien) ce n'est pas forcément facile à affirmer ou infirmer, dans l'ambiguité je ferais une superclass quadrilatere dont je dérive rectangle et carré comme cela plus de problème de polémique

  4. #4
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut
    Citation Envoyé par Franck SORIANO Voir le message
    Quoi donc ? Le carré qui dérive du rectangle ?
    Exactement.
    Citation Envoyé par Franck SORIANO Voir le message
    Tu as des exemples ?
    http://www.developpez.net/forums/d18...a/#post1373282
    http://www.dotnetguru2.org/index.php...&c=1&tb=1&pb=1

  5. #5
    Membre Expert

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Par défaut
    Tu peux être plus précis ? je ne vois ou on parle du carré et du rectangle, et vu la longueur des posts, j'ai pas trop envie de fouiller.

    Merci, je me suis bien marré . L'auteur est contre l'héritage parce qu'il ne le maîtrise pas et montre les problèmes qu'on rencontre lorsqu'on fait n'importe quoi.
    Il ne dit pas que faire dériver le carré du rectangle est une aberration de conception.
    Regardons ses explications :

    La classe Carre ne va pas seulement hériter de propriétés dont elle n’a pas besoin, mais aussi éventuellement de méthodes qui n’ont peut-être aucun sens pour elle.
    Ben la, on n'est plus dans le cas du Rectangle et du Carré. Nous on parle des objets mathématiques. Hors un carré est un rectangle. Tout ce qui s'applique à un rectangle s'applique indifféremment à un carré.
    Dans son cas, sa classe Rectangle n'était déjà plus un rectangle. Mais un rectangle plus autre chose. Et il nous dit maintenant que ce quelque chose ne concerne pas le carré... Donc normalement dans ce cas, tu ne dérives pas du rectangle. Tu fais plutôt un coup de refactoring pour éclater la classe "Rectangle + Quelque chose", en "Rectangle" puis "Quelque chose" qui dérive de Rectangle.

    D’autres problèmes plus graves peuvent surgir. Par exemple la fonction suivante apparaît dans mon application. Elle est parfaitement légale :

    void MaFonction(Rectangle r) {…}

    Tout objet implémentant Rectangle peut être reçu en paramètre et donc en particulier un Carre.

    Supposons que le code de Mafonction() a besoin de calculer 1/(Hauteur – Largeur) . Cette opération ne pose jamais de problème pour un Rectangle.
    Faux : Rien n'interdit d'avoir un Rectangle particulier, avec Hauteur = Largeur. Ce n'est pas parce que tu as un rectangle que tu peux en déduire que Hauteur-Largeur<>0.
    Donc son code était boggué dès le départ et ne marchait déjà pas avec un rectangle.
    Le fait de faire dériver Carré de Rectangle lui a simplement permis de découvrir son bug, mais ce n'est pas la faute du carré.

    Derrière toute la suite de sa démonstration tombe à l'eau puisque le point de départ est faux.

    Donc pour en revenir à la question du départ, je ne vois toujours rien pour justifier que faire dériver Carré de rectangle serait une abérration de conception.

    ...dans l'ambiguité je ferais une superclass quadrilatere dont je dérive rectangle et carré comme cela plus de problème de polémique
    Sauf que dans ce cas, tu perds le bénéfice de l'héritage. Si tu doit faire une fonction qui doit travailler sur un rectangle : Par exemple qui calcule son aire en faisant largeur*hauteur. Si Carré dérive de rectangle, tu peux appliquer cette fonction indifféremment sur un carré et sur un rectangle. Si carré ne dérive plus de rectangle, mais seulement de Quadrillatère, tu ne peux plus l'utiliser avec un carré...

    En fait, dans le cas du carré et du rectangle, je vois qu'en même une abérration : Le carré est un rectangle. Mais une instance particulière d'un rectangle peut très bien devenir un carré. Il suffit que sa longueur soit égale à sa largeur.
    Sa signifie qu'en changeant la valeur d'un attribut de l'objet, il faudrait que l'objet change également de type...

    Ce qui revient à dire qu'on n'a pas besoin de dériver Rectangle...

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 746
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 746
    Par défaut
    Je pense que le débat est plutôt sur les subtiles différences entre héritage (est-un) et généralisation (est une sorte de).
    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre extrêmement actif

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Je pense que le débat est plutôt sur les subtiles différences entre héritage (est-un) et généralisation (est une sorte de).
    -W
    est-un ou est-une-sorte-de c'est exactement la même chose. Une banane est un fruit ou une banane est une sorte de fruit c'est du pareil au même.


    Citation Envoyé par Franck SORIANO
    Sauf que dans ce cas, tu perds le bénéfice de l'héritage.Si tu doit faire une fonction qui doit travailler sur un rectangle : Par exemple qui calcule son aire en faisant largeur*hauteur. Si Carré dérive de rectangle, tu peux appliquer cette fonction indifféremment sur un carré et sur un rectangle.Si carré ne dérive plus de rectangle, mais seulement de Quadrillatère, tu ne peux plus l'utiliser avec un carré..

    Minute, une petite minute.

    Par exemple une superclass Quadrilatere ensuite subclasser en Quad1Dimension, Quad2Dimension.....pour enfin subclasser en carré et rectangle.

    Bon à partir de là rien ne m'empêche de définir Quadrilatere comme abstract et de définir une méthode calculeAire. Carre et Rectangle dérivant de Quadrilatere (par généralisation)ils héritent bien de la méthode on peut faire carre.calculeAire() et rect.calculeAire().

    Enfin cela pourrait être une solution avec héritage, en alternative de dériver un carre d'un rectangle.

    Ce qui revient à dire qu'on n'a pas besoin de dériver Rectangle...
    Deriver d'un rectangle bof...l'agréger oui !

    je me demande si le pattern adaptateur ne ferait pas l'affaire...

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3
    Par défaut Héritage classes carré/rectangle
    Lors de mon cours de java, on nous a mis en garde à propos de cet exemple, en nous faisans remarquer que justement c'était rectangle qui héritait de carré, même si ce n'est pas la vue des mathématiques. Et du coup, les problèmes sont beaucoup moins nombreux... il ne reste plus qu'un problème principal : si l'on définit un rectangle ayant deux côtés de même longueur...

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    ayant lu ce débat, et ayant pas mal travaillé en géométrie (mais pas en langage objet, mais en orienté objet), je vous suggère une classification autre :

    classe de base : polygone

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    234
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 234
    Par défaut
    Il est sûr et certain que rectangle n'hérite pas de carré, car la modélisation orientée objet se doit de montrer une réalité et non pas de modéliser une conception pour arranger la réalisation (ce qui est une approche horrible).

    On ne peut pas dire que le rectangle le losange ou le carré doivent posséder des méthodes supplémentaires à celle que l'on peut définir dans quadrilatère, ce qui ne rend pas obligatoire l'utilisation de l'héritage.

    Je verrais une approche par état :
    - une classe QuadrilatereType qui définit les différents types de quadrilatère (carré, rectangle, parrallélogramme) avec une méthode isQuadrialtereOfThisType(Quadrilatere q) ;
    - une classe quadrilatère immuable qui a une methode QuadrilatereType getTypeOfQuadrilatere().

    Le fait de spécialiser n'oblige pas à utiliser l'héritage, il existe toujours bcp de moyens pour modéliser un concept (et le plus instinctif n'est pas forcément le bon).

  11. #11
    Membre émérite Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Par défaut
    Quand je lis cet article:

    http://www.mathsgeo.net/rep/qpar.html

    Dont j'ai pris quelques définitions:

    Le terme de parallélogramme désigne en fait une grande famille de quadrilatères aux nombreuses propriétés.
    Le carré: est un quadrilatère qui est à la fois rectangle et losange.
    Le losange: est un quadrilatère qui a ses quatre côtés de même longueur.
    Le rectangle: est un quadrilatère qui possède 4 angles droits.

    Je serais plus tenté de parlé d'état d'une classe parallèlogramme, {Losange,Rectangle} avec Carré=Rectangle+Losange, héritant de quadrilatère.

    J'écris ceci par rapport à un post qui dit que rectangle hérite de carré.

  12. #12
    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 : 52
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    "Est-ce que le carré dérive de rectangle, ou alors est-ce le rectangle qui dérive du carré ?"

    Ah.... j'adore ces questions pièges. Car le piège n'est pas là où on le pense !! La réponse est : "ni l'un, ni l'autre !!"

    une bonne réponse possible est "un Carré est une instance de la classe Rectangle"
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    Rectangle carré = new Rectangle(length,length);
    Et dans ce cas, on peut réellement dire qu'un carré est un rectangle:
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    assert(carré instanceof Rectangle);

    De cette définition, on peut créer une classe Carré qui utilisera un rectangle comme attribut privé.
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class Carré {
        private Rectangle instance;
        public Carré(int length) {
            this.instance = new Rectangle(length,length);
        }
    }
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

Discussions similaires

  1. Héritage, classe virtuelle
    Par Anium dans le forum C++
    Réponses: 3
    Dernier message: 21/05/2008, 09h18
  2. Héritage, classe de base
    Par Melem dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 25/02/2008, 15h45
  3. Héritage classe template->classe template
    Par zabibof dans le forum Langage
    Réponses: 5
    Dernier message: 11/08/2007, 11h05
  4. Réponses: 5
    Dernier message: 10/01/2007, 02h08
  5. Réponses: 4
    Dernier message: 26/01/2006, 10h48

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