sortie: em> ne devrait-il pas être:? em>
B-> Bonjour! d'explicite.
A-> Bonjour! d'explicite. P> Pourquoi ne peut-il pas lancer explicitement (ihello) un appel ihello.hello () de la classe A? h2>
4 Réponses :
Non, ça ne devrait pas. P>
L'appel à Lorsqu'une interface est explicitement implémentée plus d'une fois dans la hiérarchie de type, la mise en œuvre du type le plus dérivé est utilisée. (Lorsque cela est appelé via l'interface.) P>
à partir de la section 13.4.4 de la spécification C # 3.0: P>
Cartographie de l'interface pour une classe ou
structure C localise une implémentation pour
chaque membre de chaque interface
spécifié dans la liste des classes de base de C.
La mise en œuvre d'un particulier
Membre d'interface I.M, où je suis le
interface dans laquelle le membre m est
déclaré, est déterminé en examinant
chaque classe ou structure S, commençant par
C et répéter pour chaque successive
classe de base de c, jusqu'à ce qu'un match soit
Situé: P>
Hello code> est équivalent à celui de commenté - l'itinéraire pour obtenir un ihello code> n'a pas d'importance (sauf s'il ne nécessite que la vérification ou la conversion d'exécution ); Le type de compilation est juste ihello code> de chaque sens et le mappage d'interface est identique mais vous y arrivez. P>
+1. À partir d'une perspective de niveau inférieure, il y a un seul emplacement de méthode pour ihello.hello code> dans la machine à livrer pour la classe B, où la mise en œuvre va être levée.
Merci pour la réponse rapide! Bien que, selon les règles de l'OOP, une référence d'un point de classement de base à un objet d'ombres de classe dérivées sur les champs et les méthodes de la classe dérivée ne présente pas dans la classe de base. Est-ce alors une exception à cette règle?
@Naximus Le système de type sait toujours exactement ce que le type de l'objet est. Affectation d'une instance B code> à un champ A code> indique "laisse i> mon code Accédez à l'instance référencée par ce champ comme s'il s'agissait de Tapez A code> " i>. Casting ultérieurement le champ vers ihello code> dit "Temporairement I> Mon code Accédez à l'instance référencée par ce champ comme s'il s'agissait de type ihello code> iHello code> " I>. L'instance référencée toujours est et sera toujours de type B code>. Cela seul détermine le résultat. Seule la fois que de telles actions font quelque chose d'autre que «de la perspective de changement» d'une instance, c'est quand il y a des opérateurs de distribution définis pour cela.
(suite ...) Pour faire une métaphore géométrique visuelle semi-correcte très abstraite: pensez à l'objet comme étant multi-dimensionnelle, et votre code regarde l'objet avec un spectateur capable de visualiser l'objet à travers toutes les dimensions différentes. L'objet mon aspect très différent en fonction de la dimension de votre code à partir de (par exemple, Tesseract ) , mais c'est toujours le même objet, et les opérateurs d'affectation et de distribution changent simplement dans quelles dimensions le visualiseur voit l'objet. ... Mais peut-être que cette explication est TOO B> Résumé pour être utile? Je ne sais pas.
Non, lorsque vous créez une méthode Lorsque vous créez une méthode forte> virtuelle forte>, alors quel que soit le type que vous lancez la référence à, la mise en œuvre du type réel de l'objet est utilisée (c'est-à-dire que vous avez créé un B, donc lorsque vous avez appelé. (Quel que soit l'objet) .hello, appelé B.Hello) P>
La différence cruciale est qu'un appel est virtuel et l'autre n'est pas. P>
(Note aux lecteurs: La question a été modifiée après la rédaction de cette réponse. La première version de la question ajoutée nouvelle chaîne tostring () code> dans le mélange, augmentant la confusion. Pour plus de détails, voir révisions des interfaces explicites avec héritage? - Overflow de pile .)
(a) A ne fait rien. La référence est déjà déclarée sous la forme d'un tel casting à une volonté n'a aucun effet. P>
Même si votre référence est déclarée comme un, l'objet qu'il fait référence est de type B. Si vous lancez cet objet à Ihello, un appel à Hello () appellera la mise en œuvre explicite de l'objet B de Hello. P>
La sortie est exactement comme prévu. P>
(Note aux lecteurs: La question a été modifiée après la rédaction de cette réponse. La première version de la question ajoutée nouvelle chaîne tostring () code> dans le mélange, augmentant la confusion. Pour plus de détails, voir révisions des interfaces explicites avec héritage? - Overflow de pile .)
Non, ça ne devrait pas. P>
Lorsque vous appelez une méthode virtuelle, peu importe le type de référence. La méthode appelée est déterminée par le type réel de l'objet, pas le type de référence. P>
Lorsque vous créez une instance de la classe Également si vous remplacez la méthode B code>, le type réel de l'objet est B code>. La raison pour laquelle il imprime "c'est la classe A." code> est que vous n'avez pas remplacé la méthode code> tostring code> dans la classe B code>, vous avez ombragé Utilisant le mot-clé nouveau code>. Par conséquent, la classe B code> a deux méthodes tostring code>, une héritée à partir de la classe A code> et celle qui les ombres. Si vous utilisez une référence A code> pour appeler la méthode tostring code>, la méthode héritée est appelée, mais si vous auriez utilisé un B code> référence à appeler La méthode d'ombrage serait appelée, imprimant "c'est la classe b." code>. p>
tostring code> dans la classe B code> au lieu de l'ourdler, il imprimerait "C'est la classe b." Code > Quel que soit le type de référence. P>
(Note aux lecteurs: La question a été modifiée après la rédaction de cette réponse. La première version de la question ajoutée nouvelle chaîne tostring () code> dans le mélange, augmentant la confusion. Pour plus de détails, voir révisions des interfaces explicites avec héritage? - Overflow de pile .)