Was ist der Unterschied zwischen einer abstrakten Klasse und einer Klasse mit nur geschützten Konstruktoren? Sie scheinen mir ziemlich ähnlich zu sein, da Sie keines von beiden instantiieren können.
BEARBEITEN:
Wie würden Sie eine Instanz in einer abgeleiteten Klasse mit einer Basisklasse mit einem geschützten Konstruktor erstellen? Zum Beispiel:
%Vor%Sie können eine Klasse mit geschützten Konstruktoren innerhalb der Klasse selbst instanziieren - in einem statischen Konstruktor oder einer statischen Methode. Dies kann verwendet werden, um ein Singleton oder ein Fabrik-Ding zu implementieren.
Eine abstrakte Klasse kann überhaupt nicht instanziiert werden - die Absicht besteht darin, dass eine oder mehrere untergeordnete Klassen die Implementierung abschließen und diese Klassen instanziiert werden
Bearbeiten:
Wenn Sie ProtectedConstructor.GetInstance();
anstelle von new ProtectedConstructor();
aufrufen, funktioniert es. Vielleicht können geschützte Konstrukteure nicht so aufgerufen werden? Aber geschützte Methoden können es sicherlich.
Hier ist ein interessanter Artikel zum Thema.
Meistens gibt es wenig praktischen Unterschied, da beide nur über eine Unterklasse generiert werden können.
Das Markieren einer Klasse abstract
hat jedoch zwei Vorteile:
Mit geschützten Konstruktoren ist es immer noch möglich, eine Instanz der Klasse auf zwei Arten zu erstellen. Sie können Activator.CreateInstance mit BindingFlags.NonPublic verwenden, oder Sie können eine Factory-Methode verwenden, die in definiert ist die Klasse (oder eine Unterklasse), um eine Instanz der Klasse zu erstellen. Eine als abstrakt markierte Klasse kann jedoch nicht erstellt werden.
Sie verdeutlichen Ihre Absicht, indem Sie die Klasse abstract
markieren. Für mich persönlich ist dies der beste Grund, dies zu tun.
Von außen, Black-Box-Perspektive, ja, sie sind ähnlich, da Sie keines von beiden instanziieren können. Sie können jedoch never eine abstrakte Klasse instanziieren, in der Sie eine Klasse mit nur geschützten Konstruktoren aus der Klasse selbst oder aus einem Erben erstellen können.
Ihr Beispiel ist fehlerhaft, weil Sie im Fall von getInstance eine ProtectedConstructor-Klasse erstellt haben und erwarten, dass Sie sie als DerivedClass downcast. Stattdessen benötigen Sie eine etwas vollständigere Implementierung, bei der die abgeleitete Klasse einen Konstruktor hat:
%Vor%Ungeachtet der hauptsächlichen Unterschiede bei der Verwendung abstrakter Klassen besteht die Definition abstrakter Methoden, die von Unterklassen implementiert werden müssen, für die Sie jedoch keine Standardimplementierung bereitstellen möchten. Angenommen, Sie haben eine Art von Thread-Klasse mit einer Run-Methode. Sie möchten sicherstellen, dass bei jedem Aufruf von "Run" zuerst die Protokollierung durchgeführt wird und dann die eigentliche Arbeit des Threads ausgeführt und die Protokollierung beendet wird. Sie könnten eine abstrakte Thread-Klasse wie folgt schreiben:
%Vor%Eine andere Sache, die man beachten sollte, dass ich andere Leute nicht erwähnt habe, ist, dass Ihr Code in Zukunft gepflegt werden könnte. Wenn der Betreuer einer Klasse einen öffentlichen Konstruktor hinzufügt, kann er instanziiert werden. Dies könnte Ihr Design zerstören, also sollten Sie es verhindern (oder Design, um es unterzubringen).
Um zu verhindern, dass andere Personen solche Änderungen vornehmen, können Sie Ihren Code kommentieren. Oder, wie andere Leute sagten, verwenden Sie "abstrakt", um Ihre Absicht explizit zu dokumentieren.
Nun, der erste Unterschied, der Ihnen in den Sinn kommt, ist, dass eine abstrakte Klasse nicht instanziiert werden kann, aber eine Klasse mit geschützten Konstruktoren instanziiert werden könnte, werfen Sie eine andere öffentliche Methode.
Ein gängiges Beispiel dafür könnte etwas wie das Singleton-Muster sein: Ссылка
Wenn Sie die statische Verwendung der Klasse nur zulassen (d. h. nicht als reine Basisklasse verwenden), sollten Sie stattdessen das Schlüsselwort static verwenden. Die CLR verhindert, dass Instanzen der Klasse über eine beliebige Methode einschließlich Reflection (AFAIK) erstellt werden.
Tags und Links c# constructor abstract-class protected