Ich bin neu in OOP und habe ein paar Fragen.
Warum können in einer Schnittstelle deklarierte Methoden keine Modifikatoren (public, private usw.) haben.
In diesem Code:
Beide Methoden benötigen keine Modifikatoren, aber wenn ich keine Schnittstelle wie X.add()
oben verwende, muss ich die Implementierung veröffentlichen. Warum?
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
oderstatic
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.
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:
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
oderstatic
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 vonC
angegeben ist. Die Implementierung eines bestimmten Interface-MembersI.M
, wobeiI
die Schnittstelle ist, in der das MemberM
deklariert wird, wird bestimmt, indem jede Klasse oder StrukturS
untersucht wird, beginnend mitC
und für jede sukzessive wiederholt wird Basisklasse vonC
, bis eine Übereinstimmung gefunden wird
Wenn
S
eine Deklaration einer expliziten Interface-Member-Implementierung enthält, dieI
undM
entspricht, dann ist dieses Member die Implementierung vonI.M
Andernfalls, wenn
S
eine Deklaration eines nicht statischen öffentlichen Mitglieds enthält, dasM
entspricht, dann ist dieses Mitglied die Implementierung vonI.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
:
Wenn Sie I.M
explizit implementieren, lautet die Syntax
return-type I.M(parameter-list)
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
:
während
%Vor%Hilft das?
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?
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.
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. "
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.
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.
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.
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.