En fait c'est logique, même si cette méthode est déclarée virtuelle et donc redéfinissable dans B, cela n'implique pas qu'elle doive nécessairement être redéfinie vu qu'elle n'est pas virtuelle pure.
Pas tout-à-fait : une méthode, quelle qu'elle soit, n'a pas besoin d'être virtuelle (pure ou non) pour pouvoir être redéfinie. En fait, tu n'as même pas besoin de la déclarer dans les classes dérivées dès lors que celles-ci en héritent de la classe supérieure. Ca veut dire notamment que tu n'as pas besoin de déclarer une méthode virtuelle (pure) à la racine de ton graphe simplement parce que tu comptes la faire apparaître un peu plus loin. C'est même fondamentalement le contraire : le procédé est fait pour t'éviter d'avoir à y penser à l'avance.
D'autre part, être confronté à des héritages en diamant est une chose relativement fréquente en C++, mais ils sont généralement dus à une erreur de conception dans le modèle et pas à une limitation technique. Au pire, ils traduisent un conflit, au mieux, ils mettent généralement en évidence des notions jusque là implicites.
Mais ton erreur d'analyse, dans ce cas précis, est de considérer chaque classe dérivée comme un sous-ensemble d'une classe plus générale (ce que N est à R, par exemple), alors qu'il s'agit au contraire d'une extension de la classe précédente (comme Z par rapport à N). Chaque classe contient implicitement la classe mère en entier, plus d'autres choses.
Il est humainement facile de trancher entre une classe qui définit property1() et une autre qui ne se prononce pas, mais c'est plus dur de le faire si elles ont des opinions antagonistes : tu pourrais très bien définir une classe D qui, héritant de deux classes, soit à la fois un anneau intègre et un anneau non-intègre, ce qui n'a pas de sens.
Si ce problème se résout parce qu'on sait qu'il y a prédominance ou récessivité, alors celles-ci doivent être définies. Mais ici, on voit que c'est le modèle objet même qui doit être revu. Le Java ne permettant pas d'hériter de plusieurs classes à la fois, c'est un problème qui est automatiquement contourné (donc jamais rencontré), mais pas résolu.
, auriez-vous des conseils pour l'exemple que je donnais à la fin ?
J'en ai un : Contrairement à Java, le C++ n'impose pas que tu définisses tes méthodes à l'intérieur de ta classe. C'est même mieux si tu sépares tes déclarations et définitions dans des fichiers .h et .c distincts. Ainsi, le .h peut être directement utilisé par les programmes sources externes qui utiliseront ta classe.
D'autre part, toute fonction membre définie dans la déclaration de la classe est automatiquement considérée inline, et c'est rarement souhaitable.
[^] # Re: Tes "virtual" sont mals placés
Posté par Obsidian . En réponse au message Autour de l'héritage multiple et des méthodes virtuelles.. Évalué à 3.
Pas tout-à-fait : une méthode, quelle qu'elle soit, n'a pas besoin d'être virtuelle (pure ou non) pour pouvoir être redéfinie. En fait, tu n'as même pas besoin de la déclarer dans les classes dérivées dès lors que celles-ci en héritent de la classe supérieure. Ca veut dire notamment que tu n'as pas besoin de déclarer une méthode virtuelle (pure) à la racine de ton graphe simplement parce que tu comptes la faire apparaître un peu plus loin. C'est même fondamentalement le contraire : le procédé est fait pour t'éviter d'avoir à y penser à l'avance.
D'autre part, être confronté à des héritages en diamant est une chose relativement fréquente en C++, mais ils sont généralement dus à une erreur de conception dans le modèle et pas à une limitation technique. Au pire, ils traduisent un conflit, au mieux, ils mettent généralement en évidence des notions jusque là implicites.
Mais ton erreur d'analyse, dans ce cas précis, est de considérer chaque classe dérivée comme un sous-ensemble d'une classe plus générale (ce que N est à R, par exemple), alors qu'il s'agit au contraire d'une extension de la classe précédente (comme Z par rapport à N). Chaque classe contient implicitement la classe mère en entier, plus d'autres choses.
Il est humainement facile de trancher entre une classe qui définit property1() et une autre qui ne se prononce pas, mais c'est plus dur de le faire si elles ont des opinions antagonistes : tu pourrais très bien définir une classe D qui, héritant de deux classes, soit à la fois un anneau intègre et un anneau non-intègre, ce qui n'a pas de sens.
Si ce problème se résout parce qu'on sait qu'il y a prédominance ou récessivité, alors celles-ci doivent être définies. Mais ici, on voit que c'est le modèle objet même qui doit être revu. Le Java ne permettant pas d'hériter de plusieurs classes à la fois, c'est un problème qui est automatiquement contourné (donc jamais rencontré), mais pas résolu.
J'en ai un : Contrairement à Java, le C++ n'impose pas que tu définisses tes méthodes à l'intérieur de ta classe. C'est même mieux si tu sépares tes déclarations et définitions dans des fichiers .h et .c distincts. Ainsi, le .h peut être directement utilisé par les programmes sources externes qui utiliseront ta classe.
D'autre part, toute fonction membre définie dans la déclaration de la classe est automatiquement considérée inline, et c'est rarement souhaitable.