Nein, sollte es nicht.
Der Aufruf von Hello
entspricht dem auskommentierten - die Route zum Abrufen von IHello
spielt keine Rolle (es sei denn, es ist eine Überprüfung oder Konvertierung der Ausführungszeit erforderlich); Der Typ der Kompilierzeit ist nur IHello
, und das Interface-Mapping ist das gleiche, wie Sie es auch bekommen.
Wenn eine Schnittstelle mehr als einmal in der Typhierarchie explizit implementiert wird, wird die Implementierung im am meisten abgeleiteten Typ verwendet. (Wenn über die Schnittstelle aufgerufen.)
Aus Abschnitt 13.4.4 der C # 3.0-Spezifikation:
Interface Mapping für eine Klasse oder struct C lokalisiert eine Implementierung für jedes Mitglied jeder Schnittstelle in der Basisklassenliste von C. angegeben Die Implementierung eines bestimmten Interface-Mitglied I.M, wo ich das ist Schnittstelle, in der das Mitglied M ist erklärt, wird durch Prüfung festgestellt jede Klasse oder Struktur S, beginnend mit C und Wiederholen für jeden sukzessive Basisklasse von C, bis eine Übereinstimmung ist gefunden:
- Wenn S eine Deklaration enthält eines expliziten Schnittstellenmitglieds Implementierung, die I und M entspricht, dann ist dieses Mitglied die Implementierung von I.M.
- Andernfalls, wenn S eine Deklaration eines nicht statischen öffentlichen Mitglieds enthält, das M entspricht, dann ist dieses Mitglied die IM-Implementierung. Wenn mehr als ein Mitglied übereinstimmt, ist nicht angegeben, welches Mitglied die IM-Implementierung ist auftreten, wenn S ein konstruierter Typ ist, bei dem die beiden im generischen Typ deklarierten Elemente unterschiedliche Signaturen haben, aber die Typargumente ihre Signaturen identisch machen.
(A) a tut nichts. Der Verweis ist bereits als ein deklariert, so dass es zu A wird keine Wirkung haben.
Obwohl Ihr Verweis als A deklariert ist, ist das Objekt, auf das er verweist, vom Typ B. Wenn Sie dieses Objekt in IHallo umwandeln, ruft ein Aufruf von Hello () die explizite Implementierung von Hello von Objekt B auf.
Die Ausgabe ist genau wie erwartet.
Nein, wenn Sie eine neue -Methode (ToString) erstellen, ist diese nicht virtuell. Neu bedeutet nur, dass es Ihnen nichts ausmacht, die Version in der Basisklasse zu "verstecken" - wenn Sie sie also mit einem Verweis aufrufen, den Sie auf einen bestimmten Typ (A) umgewandelt haben, führt sie die Methode in Klasse A aus, unabhängig davon der tatsächliche Typ des Objekts, das Sie anrufen. (Sie haben A.ToString () aufgerufen, damit A.ToString ())
ausgeführt wurdeWenn Sie eine virtuelle -Methode erstellen, wird unabhängig vom Typ, auf den Sie die Referenz referenzieren, die Implementierung vom tatsächlichen Typ des Objekts verwendet (dh Sie haben ein B erstellt, also beim Aufruf (was auch immer das Objekt ist). Hallo, es nannte B. Hallo)
Der entscheidende Unterschied ist, dass ein Anruf virtuell ist und der andere nicht.
Nein, sollte es nicht.
Wenn Sie eine virtuelle Methode aufrufen, ist es egal, um welche Art von Referenz es sich handelt. Die Methode, die aufgerufen wird, wird durch den tatsächlichen Typ des Objekts bestimmt, nicht durch den Typ der Referenz.
Wenn Sie eine Instanz der Klasse B
erstellen, ist der tatsächliche Typ des Objekts B
. Der Grund dafür, dass "This is class A."
gedruckt wird, ist, dass Sie die Methode ToString
in der Klasse B
nicht überschrieben haben. Sie haben sie mit dem Schlüsselwort new
schattiert. Daher hat die B
-Klasse zwei ToString
-Methoden, eine von der Klasse A
geerbte und eine, die sie schattiert. Wenn Sie eine A
-Referenz verwenden, um die ToString
-Methode aufzurufen, wird die geerbte Methode aufgerufen. Wenn Sie jedoch eine B
-Referenz verwendet hätten, um sie aufzurufen, würde die Shadowing-Methode aufgerufen und "This is class B."
ausgedruckt.
Auch wenn Sie die Methode ToString
in der Klasse B
überschreiben, anstatt sie zu spiegeln, würde% code_de% unabhängig vom Typ der Referenz ausgegeben.
Tags und Links c# inheritance explicit-interface