Warum können wir nicht ändern access-modifier beim überschreiben von Methoden in C#?
In C# können wir nicht ändern access-modifier beim überschreiben einer Methode aus der Basisklasse.
z.B.
Class Base
{
**protected** string foo()
{
return "Base";
}
}
Class Derived : Base
{
**public** override string foo()
{
return "Derived";
}
}
Dieser ist nicht gültig in C#, wird Es geben compile-Zeit-Fehler.
Ich will wissen, der Grund, warum es nicht erlaubt ist. Ist es ein technisches problem oder kann es zu etwas führen, was nicht im Einklang in Bezug auf die Zugangs-Beschränkung???
InformationsquelleAutor Rumit Parakhiya | 2011-06-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ändern des access-modifier einer Methode in einem abgeleiteten Typ ist sinnlos, dass ist der Grund, warum es nicht erlaubt ist:
Fall 1: Überschreiben mit einer restriktiveren Zugang
Diesem Fall ist offensichtlich nicht zulässig, da die folgende situation:
Nun könnten wir sagen:
Fall 2: Überschreiben mit einer weniger einschränkenden zugriffsmodifizierer
Was ist der Punkt? Verbergen die Methode-und Sie sind fertig.
Natürlich, wenn Sie einen Anruf über die base geben, die Sie nicht haben Zugang zu der neu definierten Methode in den abgeleiteten Typ, aber das ist im Einklang mit, wie der Autor des Basistyps wollte Dinge zu sein, so haben Sie kein "Recht" zu ändern. Wenn Sie möchten, dass die Besonderheiten der abgeleiteten Klasse aufrufen, von der abgeleiteten Klasse, in dem Fall die
new
Methode funktioniert bestens.EDIT: Erweitern Fall 2
Was ich bin versucht zu sagen, dass im Fall 2 ist, dass Sie bereits die Mittel haben, zu ändern, die Zugänglichkeit von jeder Methode (virtuell oder nicht), wenn Sie ändern möchten Zugänglichkeit.
Betrachten Sie den folgenden code:
Mit der
new
Keywords, die Sie effektiv erstellt eine neue virtuelle Methode für IhreDerived
Klasse mit dem gleichen Namen und Signatur. Beachten Sie, dass es ERLAUBT ist, zu erklären, einenew
Methodevirtual
, so dass jede Klasse, die vonDerived
wird erlaubt, um es zu überschreiben.Was nicht erlaubt ist, jemanden zu haben, tun Sie den folgenden:
Aber diese Tatsache hat nichts damit zu tun, in der Lage zu überschreiben
WhoAmI()
oder nicht. Was auch immer der Fall in dieser situation kann es nie sein, weilBase
nicht erklärenpublic
WhoAmI()
.So, in einem theoretischen C#, wo
Derived.WhoAmI()
könnte überschreibenBase.WhoAmI()
es gibt keinen praktischen nutzen im tun, weil Sie nie in der Lage, rufen Sie die virtuelle Methode aus der Basisklasse na ja, dienew
option bereits erfüllt Ihre Anforderungen.Ich hoffe das macht es klarer.
Finden Sie Bearbeitungen, die Sie auf meine Antwort für die Begründung auf Fall 2.
Danke für die Hilfe. Es klärte meine Zweifel.
Ich verstehe nicht, wie Sie sagen, "es gibt keinen praktischen nutzen im tun, weil Sie nie in der Lage, rufen Sie die virtuelle Methode aus der Basisklasse sowieso". Es ist sehr üblich, für eine Basisklasse zu definieren, die eine
protected virtual
Methode zum aktivieren der Unterklasse, um Verhalten zu ändern, ausgestellt durch die Implementierung in der Basisklasse. Die Frage bezüglich Fall 2 ist, wie beide 1. überschreibenprotected vritual MemberName
und 2. setzen Sie eine öffentliche member-namensMemberName
. Es klingt wie es unmöglich ist, ohne Austausch der einzelnen Unterklasse mit zwei Unterklassen, um inkrementelloverride
und dannnew
.Ich brauche es nicht Sie überhaupt. Wo habe ich gesagt, dass die geschützten Mitglieder und überschreiben Sie nicht nützlich ist? Der OP fragte, warum beim überschreiben solche Methoden sind nicht erlaubt, ändern Sie den zugriffsmodifizierer, und meine Antwort adressiert genau diese Sorge: das überschreiben einer geschützten Methode und ändern dessen access modifier hilft Ihnen in genau das, was? Und wie ist es besser als neue?
InformationsquelleAutor InBetween
OK, fand ich einen kleinen Hinweis von Eric Lippert in den Kommentierten C# - Referenz:
Also dies ist eine gewollte Regel, um zu verhindern, dass die "brüchige Basis-Klasse" - problem und bieten eine bessere Versionsverwaltung, D. H. weniger Probleme, wenn eine Basisklasse ändert.
Aber beachten Sie, dass es hat nichts mit Sicherheit zu tun, geben Sicherheit oder den Objekt-Zustand.
Ich kann nicht einen Sinn, dass der 1. Teil des Satzes.
sorry Handy-AutoVervollständigen...Was ich sagen wollte ist, dass ich die Möglichkeit zum ändern des Zugriffs beim überschreiben sinnlos.
Sie sagen also, dass der compiler-Fehler erhalten Sie in einer Unterklasse, wenn die Sichtbarkeit einer Basisklasse Mitglied änderungen vermeidet der spröden base-class-problem zwingt den Entwickler zur überprüfung der Unterklasse an diesem Punkt. Dass tatsächlich Klang nützlich.
InformationsquelleAutor Henk Holterman
Wenn Sie zum ändern der Sichtbarkeit Modifikatoren aus einer eher restriktiven Modifikator zu einer weniger restriktiven Modifikator Sie erlauben Klasse Kunden Zugang zu Methoden, die für den internen Gebrauch. Im wesentlichen, Sie haben ein Mittel, um zu alter Klasse Zustand, die möglicherweise nicht sicher sein.
class Derived { public string foo2() { return foo(); } }
also ich glaube nicht, dass dein argument genug.Das Gesicht, das Sie umgehen können Klasse visibility modifiers ändert nichts an der Tatsache, dass Sie Zugang zu Methoden, die für den internen Gebrauch Probleme verursachen können. Kann es sein, dass Fall, dass keine Probleme auftreten würden, oder Sachen können die Luft zu sprengen. Wenn Sie feststellen, dass die Verpackung einer nicht-öffentlichen Mitglied öffentlich zugänglich zu machen, nicht dazu führen, dass problem, das Klasse design ist wahrscheinlich falsch. Dies bedeutet nicht, dass die Umgehung visibility modifiers ist eine gute Idee.
Ich erwarte eine Antwort in Bezug auf Schnittstellen und substitution. Eine abgeleitete Klasse kann immer hinzufügen zu der öffentlichen Schnittstelle, kann es nicht reduzieren. Und das argument, über das Objekt-Zustand einfach nicht halten.
Natürlich eine abgeleitete Klasse kann die Schnittstelle, aber das war nicht die Frage. Die Frage war, warum die änderung einer bestehenden Methode, die Sichtbarkeit zu einer großzügigeren Ebene durch überschreiben ist nicht erlaubt. Die Frage bezog sich nicht auf Verpackung oder die Verwendung eines nicht-öffentlichen Verfahren. Überschreiben, wie gezeigt, in der Frage, wird nicht verhindern, dass die Klasse substitution, noch eine dding eine zusätzliche öffentliche Methoden (es sei denn, Kunden check-Methode meta-Daten).
Ich glaube, es war die Frage. Aber siehe meine Antwort über "brüchige Basis-Klasse'.
InformationsquelleAutor John Percival Hackworth
Können Sie machen abgeleiteten Klasse zugreifen, die weniger als die Basis, aber nicht mehr. Sonst würde es widersprechen base-definition und Bereitstellung der Komponenten über das hinaus, was vorgesehen war.
wenn Sie könnten, die den Zugang beschränken würden Sie ändern das interface.
InformationsquelleAutor Kon
Verringerung der Sichtbarkeit ist nicht möglich, denn wenn
Base.Member
sichtbar war undDerived.Member
nicht sichtbar war, brechen würde, dass die ganze "Derived
ist einBase
" - Konzept in OOP. Jedoch, Erhöhung der Sichtbarkeit nicht zulässig ist vielleicht weil die Sprache, die Entwickler sind der Meinung, dass eine änderung der Sichtbarkeit wäre ein Irrtum, die meisten der Zeit. Jedoch können Sie immer dienew
keyword zu verstecken Basisklasse Mitglieder durch die Einführung ein Mitglied mit dem gleichen Namen, aber einem unterschiedlichen Verhalten. Das neue Mitglied gehört der abgeleitete Typ die Schnittstelle, also, natürlich, können Sie immer noch Zugriff auf die base-Typ-Schnittstelle, die von casting zu diesem Basis-Typ. Je nachdem, wie Sie schreiben, die Unterklasse, Ihrenew
Mitglied kann effektiv erhöhen die Sichtbarkeit-Eigenschaft der Basisklasse, aber denken Sie daran, dass die Eigenschaft der Basisklasse, kann immer noch auf die direkt zugegriffen werden (z.B. eine Unterklasse von Ihrer Unterklasse wirken könntethis
zuBase
und Ihrer Immobilie zu umgehen).Hier stellt sich die Frage, wie beide
override
undnew
des gleichen namens Mitglied (Bezeichner) in einer Unterklasse. Das ist offenbar nicht möglich. Zumindest kann ich sagen, durch Experimentieren, dasspublic new override string foo(){return "";}
ist keine syntax. Allerdings können Sie den gleichen Effekt durch die Verwendung von zwei Unterklassen:Intermediate Unterklasse (
AbstractDerived
) verwendetoverride
und stellt eine neue, anders benannte Mitglied, das die Unterklasse und sub-Unterklassen können weiterhinoverride
die Basis-Klasse angehört, wie Sie sehen, passen. Der sub-Subklasse (Derived
) verwendetnew
bei der Einführung der neuen API. Da kann man nur verwendennew
oderoverride
mit einer bestimmten id nur einmal pro Ebene der Unterklassen, müssen Sie zwei Ebenen von Unterklassen effektiv zu nutzen, sowohl auf dem gleichen identifier.So, in einer Art und Weise, können Sie durch ändern der Sichtbarkeit beim überschreiben von Methoden—es ist nur ein Schmerz, und es gibt keine syntax, die ich kenne, um es zu erreichen mit nur einer Ebene der Vererbung. Allerdings müssen Sie möglicherweise einige trick, wie diese je nachdem, welche Schnittstellen Sie versuchen, zu implementieren, und dem, was Ihre Basis-Klasse aussieht. I. e., dies kann oder kann nicht sein, was Sie wirklich tun wollen. Dennoch Frage ich mich, warum C# - nicht nur dieser, um mit zu beginnen. IOW, diese "Antwort" ist nur eine re-expression des OP ' s Frage mit einem workaround ;-).
InformationsquelleAutor binki
Gründe liegen auf der Hand. Sicherheit und Integrität der Objekte.
In diesem besonderen Beispiel, was passiert, wenn externe Entitäten start ändern der Eigenschaft des Objekts, die ist geschützt, entsprechend der Basis-Klasse. Die Dinge gehen drunter und drüber. Was ist mit dem client-code, der geschrieben wird, gegen die Basis-Klasse, zu der alle/jede abgeleitete Klasse entsprechen muss.
Ändern des Zugriffs von überschriebenen Methoden ist nur sinnlos, weil es nicht hinzufügen, dass alle Vorteile der Sprache (der Zugang) oder nicht erlaubt, denn Sie würden brechen die Basisklasse Vertrag (Beschränkung des Zugangs). Es hat nichts mit Sicherheit zu tun. Siehe meine Antwort für die Begründung.
InformationsquelleAutor this. __curious_geek
wenn es hatte andere zugriffsmodifizierer können Sie nicht wirklich in Betracht ziehen es die gleiche Methode nicht mehr. Art schlägt vor, ein problem mit dem design des Modells.
eine bessere Frage wäre, warum würden Sie wollen, ändern Sie den zugriffsmodifizierer?
InformationsquelleAutor peteisace
Überschreiben ist ein Begriff, der Ihnen ermöglicht, zu ändern oder zu ergänzen, das Verhalten von Methoden in einer Basisklasse. Überschreiben gibt Ihnen die Kontrolle, um zu schreiben, eine neue Logik für eine vorhandene Methode.
Ändern der Signatur der Methode der Basis-Klasse ist so etwas wie das schreiben eines neuen Methode anstelle von überschreiben der vorhandenen. Es widerspricht dem Zweck von überschreiben einer Methode. Also vielleicht der Grund, warum können Sie nicht ändern Sie den zugriffsmodifizierer beim überschreiben von Methoden in C#.
InformationsquelleAutor Nikhil