C # verhindern, dass die Basisklassenmethode durch einen neuen Modifikator in der abgeleiteten Klasse verborgen wird

8

Hier ist meine Situation. In Java kann ich eine Methode als final in der base / super-Klasse markieren und es gibt keine Möglichkeit, dass eine abgeleitete Klasse eine Methode derselben Signatur maskieren kann. In C # jedoch ermöglicht das neue Schlüsselwort, dass jemand meine Klasse erbt, um eine Methode mit der gleichen Signatur zu erstellen.

Siehe mein Beispiel unten. Ich muss das orignal.MyClass veröffentlichen, also bitte nicht das als Antwort vorschlagen. Dies scheint eine verlorene Funktion zu sein, die von Java zu C # übergeht.

%Vor%

EDIT: Kein Duplikat.

Alle Antworten scheinen darauf hinzuweisen, dass es nicht möglich ist zu verhindern, dass eine Methode in einer abgeleiteten Klasse verborgen / beschattet wird. Dies wurde bei der Migration von altem Java-Code zu C # offensichtlich. Eine abschließende Methode in Java wird nicht zulassen, dass jemand dieselbe Methodensignatur in einer abgeleiteten Klasse verwendet. Während es in den meisten Szenarien großartig ist, dass C # eine Methode der gleichen Signatur in der abgeleiteten Klasse zulässt, wäre es großartig gewesen, ein solches Verhalten zu verhindern, falls dies gerechtfertigt ist.

    
JAson 07.08.2013, 20:22
quelle

4 Antworten

9
  

// So verhindern Sie Folgendes:

Es gibt keine Möglichkeit, dies zu verhindern. Es ist von der Sprache erlaubt.

Beachten Sie, dass dies in der Praxis selten von Bedeutung ist. Wenn Sie erwarten, dass Ihre Basisklasse als Klasse verwendet wird, wird Ihre Methode trotzdem aufgerufen. Die Verwendung von new blendet die Methode nur aus, wenn DerivedClass von einer als DerivedClass deklarierten Variablen verwendet wird.

Dies bedeutet, dass Ihre API, wenn sie um MyClass herum aufgebaut ist, immer MyMethod aufruft, wenn Instanzen an Ihre Methoden übergeben werden.

Bearbeite als Antwort auf Kommentare:

Wenn Sie sich Sorgen machen, dass Leute Ihre Klasse im Allgemeinen unterklassifizieren, wäre die einzige wirkliche Option, die Sie haben, das Versiegeln Ihrer Klasse:

%Vor%

Dies verhindert, dass Personen vollständig eine Unterklasse erstellen. Wenn Sie jedoch zulassen möchten, dass Personen aus Ihrer Klasse abgeleitet werden, besteht keine Möglichkeit, sie daran zu hindern, Ihre Methode in ihrer Klasse zu verbergen.

    
Reed Copsey 07.08.2013 20:26
quelle
3

Sie können nicht verhindern, dass eine öffentliche Methode oder Eigenschaft maskiert wird, aber warum sollten Sie? Es wird bewusst gewählt, wer die Basisklasse dafür erweitert (d. H. Sie müssen new eingeben), also haben sie es beabsichtigt, warum versuchen und stoppen?

Vielleicht musst du dein Muster ein bisschen hochschalten? Wenn der Extender Ihre Basismethode verwenden muss, können Sie etwas Kritisches darin einfügen und ihn so zwingen, ihn aufzurufen. Natürlich ist das übel riechend, wenn es nicht richtig gemacht wird. Wenn Sie diesen Ansatz verwenden, dann markieren Sie Ihre Methode als virtual , und erwähnen Sie in der Dokumentation (oder Methodenkopf-Kommentare), dass die Basismethode aufgerufen werden muss. Auf diese Weise vermeiden Sie, dass der Extender Ihre Methode verstecken / maskieren muss (obwohl sie das immer noch tun könnte), aber sie können sie trotzdem erweitern, wenn sie möchten.

    
slugster 07.08.2013 20:28
quelle
0

Ich gehe davon aus, dass Sie wirklich verhindern wollen, dass jemand die Methode überschreibt - das Verstecken einer Methode mit new kann nicht verhindert werden, stellt aber kein Risiko für die Basisklasse dar, t ein Problem sein.

In C # Methoden können standardmäßig nicht überschrieben werden. Sie können also einfach verhindern, dass jemand eine Basismethode außer Kraft setzt, indem Sie ihn nicht als virtual oder abstract markieren. In Java sind die Methoden standardmäßig virtuell, daher ist das Versiegeln einer Methode mit final erforderlich, um ein Überschreiben zu verhindern.

    
D Stanley 07.08.2013 20:32
quelle
0

Ich denke, der einzige Weg besteht darin, eine Schnittstelle zu erstellen, in die die Methodendefinition eingefügt wird, und dann die ursprüngliche Klasse die Schnittstelle implementieren zu lassen und die Methode explizit zu implementieren:

%Vor%

Sie werden die Methode tagebuch () nicht über die Cats-Instanz verwenden.

    
Bahaa Salaheldin 10.08.2016 17:13
quelle

Tags und Links