Schnittstelle in C #

8

Ich bin neu in OOP und habe ein paar Fragen.

  1. Warum können in einer Schnittstelle deklarierte Methoden keine Modifikatoren (public, private usw.) haben.

  2. In diesem Code:

%Vor%

Beide Methoden benötigen keine Modifikatoren, aber wenn ich keine Schnittstelle wie X.add() oben verwende, muss ich die Implementierung veröffentlichen. Warum?

    
Vineet 29.01.2010, 19:09
quelle

8 Antworten

34

Eine Schnittstelle ist ein Vertrag. Es sagt: "Ich kann diese Dinge tun." Was ist der Sinn, wenn jemand Ihnen eine Instanz von IInterface übergibt, in der Sie einige der Methoden in diesem Vertrag nicht verwenden können, weil sie als nicht öffentlich markiert wurden?

Dies ist der Grund dafür, die Sprache auf diese Weise zu gestalten. Die Spezifikation dafür ist in §13.2 der Sprachspezifikation:

  

Alle Schnittstellenmitglieder haben implizit öffentlichen Zugriff. Es ist ein Kompilierungsfehler für Interface-Member-Deklarationen, die alle Modifikatoren enthalten. Insbesondere können Schnittstellen-Member nicht mit den Modifikatoren abstract , public , protected , internal , private, virtual , override oder static deklariert werden.

Was Ihren Code betrifft, so ist dies ein Beispiel für explizite Schnittstellenimplementierung . Es ist am nützlichsten, wenn eine Klasse oder Struktur zwei Schnittstellen mit jeweils einem Element mit der gleichen Signatur implementiert. Zum Beispiel definieren sowohl IEnumerable als auch IEnumerable<T> eine Methode GetEnumerator , die keine Parameter akzeptiert.

%Vor%

Beachten Sie, dass nach den obigen Definitionen jede Klasse, die IEnumerable<T> implementiert, auch IEnumerable implementieren muss. Beachten Sie, dass der Rückgabetyp nicht Teil der Signatur ist und somit ein Konflikt mit IEnumerable.GetEnumerator und IEnumerable<T>.GetEnumerator besteht. Dies soll die explizite Schnittstellenimplementierung lösen:

%Vor%

Elemente, die explizite Schnittstellenimplementierungen sind, sind nur über eine Instanz der Schnittstelle sichtbar. Also:

%Vor%

Also, in Ihrem Code

%Vor%
  

Beide Methoden benötigen keine Modifizierer, aber wenn ich keine Schnittstelle wie X.add () oben verwende, muss ich die Implementierung veröffentlichen. Warum?

Okay, es ist nicht genau klar, was Sie hier fragen. Zugriffsmodifizierer sind für explizite Schnittstellenimplementierungen nicht zulässig. Das ist 13.4:

  

Es ist ein Fehler bei der Kompilierungszeit für eine explizite Implementierung eines Schnittstellenmembers, Zugriffsmodifizierer einzuschließen, und es ist ein Fehler bei der Kompilierung, die Modifizierer abstract , virtual , override oder static einzuschließen.

Wenn eine Schnittstellenimplementierung nicht als explizite Schnittstellenimplementierung markiert ist, muss sie den Zugriffsmodifikator public haben. Dies ist 13.4.4 (Schnittstellenzuordnung):

  

Interface-Mapping für eine Klasse oder Struktur C lokalisiert eine Implementierung für jedes Mitglied jeder Schnittstelle, die in der Basisklassenliste von C angegeben ist. Die Implementierung eines bestimmten Interface-Members I.M , wobei I die Schnittstelle ist, in der das Member M deklariert wird, wird bestimmt, indem jede Klasse oder Struktur S untersucht wird, beginnend mit C und für jede sukzessive wiederholt wird Basisklasse von C , bis eine Übereinstimmung gefunden wird

     
  • Wenn S eine Deklaration einer expliziten Interface-Member-Implementierung enthält, die I und M entspricht, dann ist dieses Member 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 Implementierung von I.M .

  •   

Ein Kompilierungsfehler tritt auf, wenn Implementierungen nicht für alle Member aller Schnittstellen gefunden werden können, die in der Basisklassenliste von C angegeben sind.

Kurz gesagt, der Compiler sucht zuerst nach einer expliziten Schnittstellenimplementierung. Wenn es keinen finden kann, sucht es nach einem nicht statischen, öffentlichen Member mit der gleichen Signatur wie die Methode M , die implementiert wird. Wenn es keinen finden kann, tritt ein Kompilierungsfehler auf. Also sind die Regeln das. So implementieren Sie ein Schnittstellenmitglied I.M :

  1. Wenn Sie I.M explizit implementieren, lautet die Syntax

    return-type I.M(parameter-list)

  2. Ansonsten ist die Syntax

    public return-type M(parameter-list)

Also mit

%Vor%

Wir können das explizit implementieren:

%Vor%

oder nicht:

%Vor%

Der Unterschied ist dann, dass Explicit.Add nicht sichtbar ist, es sei denn Instanzen von Explicit werden als IAdd :

eingegeben %Vor%

während

%Vor%

Hilft das?

    
jason 29.01.2010 19:12
quelle
2

Interface ist wie ein Kontakt. Wenn eine Klasse eine bestimmte Schnittstelle implementiert, sind Sie garantiert, dass die Schnittstellenmitglieder in der Klasse existieren. Wenn es möglich wäre, die Sichtbarkeit zu ändern, würde es nicht funktionieren.

Vielleicht möchten Sie sich diese Fragen ansehen:

Woher weiß ich, wann ich eine Schnittstelle erstellen soll?
Warum kann ich keine geschützten Mitglieder der Benutzeroberfläche haben?

    
Giorgi 29.01.2010 19:12
quelle
1

Weil Schnittstellenmitglieder automatisch öffentlich sind. Sie definieren einen Vertrag über eine Schnittstelle, und es würde keinen Sinn ergeben, wenn die Mitglieder nicht öffentlich sind, da Sie sie in Ihrer implementierenden Klasse implementieren müssen.

    
George Johnston 29.01.2010 19:10
quelle
1

Direkt von Microsoft : "Schnittstellenmitglieder sind immer öffentlich, weil der Zweck einer Schnittstelle ist um anderen Typen den Zugriff auf eine Klasse oder Struktur zu ermöglichen. "

    
alchemical 29.01.2010 19:12
quelle
1

Da Ihre beiden Schnittstellen keine Methoden mit derselben Signatur definieren, benötigen Sie keine explizite Implementierung. Sie könnten Folgendes tun:

%Vor%

Das ist eine implizite Implementierung einer Schnittstelle, und jetzt ist es einfacher, diese Methoden für eine Instanz Ihrer Klasse aufzurufen. Rufen Sie einfach myInstance.add(1, 2) auf, anstatt myInstance als Instanz der Schnittstelle X zu verwenden.

    
Sarah Vessels 29.01.2010 19:19
quelle
1

Ich werde zurückgehen und die Symptome erläutern, die Sie melden, anstatt zu erklären, warum der öffentliche Modifikator unnötig ist. die anderen Antworten haben das angemessen erklärt.

Wahrscheinlich sind Sie verwirrt, weil Sie eine explizite Schnittstellenimplementierung verwenden. Wenn Sie eine explizite Schnittstellenimplementierung verwenden, müssen Sie die Objektinstanz auf diesen Schnittstellentyp umwandeln, bevor Sie ihre Methoden aufrufen können.

Wenn Sie das "X" entfernen Von Ihrer X.Add-Implementierung können Sie die Schnittstelle ohne explizite Umwandlung "sehen" und verwenden. Dies ist eine "implizite" Schnittstellenimplementierung. Solange Sie keine Namenskollisionen haben, oder einen Grund, die Schnittstellenmitglieder für normale Clients etwas weniger sichtbar zu machen, möchten Sie wahrscheinlich eine implizite Schnittstellenimplementierung bevorzugen.

    
JasonTrue 29.01.2010 19:20
quelle
0

Weil Funktionen, Felder usw., die in Interface deklariert sind, standardmäßig immer einen öffentlichen Modifikator haben. Also, wenn Sie es implementieren, müssen Sie nicht öffentlich eingeben, weil Klasse bereits jetzt Methode ist Interface-Implementierung so seine Öffentlichkeit. In Klassen sind alle Felder und Methoden privet, aber taub.

    
Kostrzak 29.01.2010 19:16
quelle
0

Dies ist der Unterschied zwischen einem Explict und Implict Implementierung einer Schnittstelle.

Normalerweise möchten Sie eine Schnittstelle implizit implementieren, was bedeutet, dass die implementierten Elemente öffentlich verfügbar sind. Dies ist sinnvoll, wenn Sie bedenken, dass die Implementierung einer Schnittstelle normalerweise bedeutet, dass eine Klasse ein bestimmtes Feature ausführen kann (z. B. über IDisposable entsorgt werden kann).

In Szenarien, in denen Sie einen Typ benötigen, um eine Schnittstelle zu implementieren, aber nicht möchten, dass diese Schnittstellenmitglieder öffentlich zugänglich sind, verwenden Sie eine explizite Implementierung. Die Mitglieder sind immer noch erreichbar, aber nur wenn der Typ über die Schnittstelle referenziert wird.

    
akmad 29.01.2010 19:19
quelle

Tags und Links