Was ist der Unterschied zwischen einer abstrakten Klasse und einer Klasse mit nur geschützten Konstruktoren? (.NETZ)

8

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%     
David Hodgson 05.02.2010, 20:57
quelle

9 Antworten

12

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.

    
Ray 05.02.2010, 20:20
quelle
2

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:

  1. 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.

  2. Sie verdeutlichen Ihre Absicht, indem Sie die Klasse abstract markieren. Für mich persönlich ist dies der beste Grund, dies zu tun.

Reed Copsey 05.02.2010 19:46
quelle
1

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.

    
Robin 05.02.2010 19:45
quelle
1

Eine abstrakte Klasse kann abstrakte Methoden haben; Methoden, die nur aus der Methodensignatur, aber keinem Body bestehen, müssen diese untergeordneten Klassen implementieren

Ernsthaft, niemand hat das schon erwähnt?

    
Powerlord 05.02.2010 20:23
quelle
1

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%     
Jon Palmer 05.02.2010 20:33
quelle
1

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.

    
Merlyn Morgan-Graham 05.02.2010 21:17
quelle
0

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: Ссылка

    
Andrew Dunaway 05.02.2010 19:48
quelle
0

Wenn Sie eine abstrakte Klasse von einer anderen abstrakten Klasse erben, müssen Sie keine abstrakten Methoden erfüllen, sondern Sie tun dies mit einer normalen Klasse mit geschützten ctors. Beispiele

%Vor%     
JMarsch 05.02.2010 20:03
quelle
0

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.

    
technophile 05.02.2010 20:24
quelle