Ich habe den folgenden Code:
%Vor%Die folgenden Anweisungen funktionieren gut und das Programm kompiliert, obwohl ich die Schnittstelle nicht implementiert habe:
%Vor%Also meine erste Frage ist: Warum hat es funktioniert?
Dann füge ich der Rechnerklasse die folgende Schnittstellenimplementierung hinzu:
%Vor%Wenn Sie die folgende Anweisung erneut versuchen:
%Vor%Die Methode, die von der Zusammenfassung überschrieben wurde, wird noch aufgerufen. Meine zweite Frage ist also: Warum hat das Programm die Methode von der abstrakten Klasse aufgerufen und nicht die Methode von der Schnittstelle?
Es gibt zwei Möglichkeiten, Schnittstellen in C # zu implementieren, entweder explizit oder implizit, aber CLR hat nur einen Implementierungstyp - den expliziten.
Wenn der C # -Compiler erkennt, dass eine Klasse eine Schnittstelle implementieren muss, sucht er nach Methoden, die den Signaturen der erforderlichen Klassen durch diese Schnittstelle entsprechen, und weist CLR an, dass es sich um Implementierungen handelt, um Code zu sparen.
Wenn Ihr C # -Compiler in Ihrem Fall sieht, dass Ihre Klasse ICalculator implementiert, sucht sie nach einer öffentlichen Methode, die der Signatur von Sum (int, int) entspricht und diese Methode als Implementierung betrachtet. Die Tatsache, dass diese Methode überschrieben wird, ist nicht wichtig.
Wenn Sie der Implementierung der Methode eine andere Bedeutung geben wollen, sollten Sie sie explizit angeben.
Nein, Sie sind es ! Ihr erster Codeblock ist vollkommen legal. Der Name und die Signatur stimmen mit den Anforderungen der Schnittstelle überein: int Sum(int x, int y)
.
Nun wird eine Signatur wie int ICalculator.Sum(int x, int y)
als explizite Schnittstellenimplementierung , was bedeutet, dass Sie nur über eine Referenz des Interface-Typs auf diese Methode zugreifen können.
Antwort für Ihre erste Qusetion
In .NET Immer wenn ein Typ (Klasse) geladen wird, erstellt die CLR eine Methodentabelle und diese Tabelle enthält Einträge für die von der Klasse definierten Methoden und die von der Klasse übernommenen Methoden. In Ihrem Fall enthält die Calculator
-Klasse die folgenden Einträge
Standardmäßig wird jede Klasse implizit von Object
-Basisklasse geerbt, sodass die Methodentabelle die Einträge für jede virtuelle Instanz enthält, die durch die Klasse Object
definiert wurde.
Ihre Klasse erbt von der abstrakten Klasse AbsCalculator
, sodass die Methodentabelle einen Eintrag für die abstrakte Klassenmethode Sum
Ihre Klasse erbt die Schnittstelle ICalculator
, sodass die Methodentabelle einen Eintrag für die Methode Sum
der Methode definiert.
Hier macht der C # -Compiler eine Annahme, dass Sie die Schnittstellenmethode implementieren, da die Methode Public
ist und die Signatur der Schnittstellenmethode und der abstrakten Klassenmethode gleich ist. Der Compiler hat also keinen Fehler gemeldet.
Antwort für Ihre zweite Frage
Während der Implementierung gibt es zwei Konzepte Implicit Interface Method Implementation
und Explicit Interface Method Implementation
In Implicit Interface Method Implementation
rufen wir die Interface-Methoden mit einer Schnittstellenreferenz auf, wie in der folgenden Abbildung gezeigt.
In Explicit Interface Method Implementation
, wenn Sie dem Namen der Methode den Namen der Schnittstelle voranstellen, wird dies zur expliziten Methodenimplementierung.