Ich denke, der Titel der Frage fasst es zusammen. Gibt es eine Zeit, in der es ein gutes Design für ein ABC wäre, Datenmitglieder zu haben? Ich habe mich gefragt, ob es eine Situation gibt, in der das in Ordnung ist. Die einzigen, die ich mir vorstellen kann, sind statisch, und selbst dann ist es eine Art Stretch.Wann kann eine abstrakte Basisklasse (nicht statische) Datenelemente haben?
Antwort
Ich sehe nicht, warum ein ABC pro-Instanz (aka nicht statische) Datenelemente nicht ordnungsgemäß haben könnte, wie benötigt, um die Methoden zu unterstützen, die es an Unterklassen liefert. Nehmen Sie den allgemeinen Fall, in dem ein ABC existiert, um eine Template-Methode DP zu liefern (die Hook-Methoden sind abstrakt) - wenn ein Teil der Funktion der Organising-Methode darin besteht, einige Instanzvariablen zu aktualisieren (z. B. wie oft Methode wurde aufgerufen), dann sollten diese Variablen natürlich auch vom ABC geliefert werden. Kannst du besser erklären, warum du das für ein schlechtes Design hältst ?!
Ich sehe dies in Plugin-Architekturen, wie Paint.NET.
Inversion von Control erfordert dies möglicherweise. Zum Beispiel haben Sie eine Reihe von Klassen, die eine Instanz von Logger nehmen, die abstrakte Klasse, auf der sie basieren, könnte einen Konstruktor in einer Membervariablen oder privaten Eigenschaft speichern (vorausgesetzt, Sie erinnern sich natürlich daran, den Basiskonstruktor grins anzurufen)
Eine abstrakte Klasse kann alle Elemente enthalten, die sie benötigt, um die Funktionalität zu unterstützen, die sie für die Klassen bereitstellt, die von ihr erben. Das heißt nicht, dass diese für die Unterklassen direkt zugänglich wären: Sie könnten nur durch Methodenaufrufe der Unterklassen oder ihrer Clients gelesen und geändert werden.
Es ist OK, wenn Ihre Daten Mitglied in Ihrer abstrakten Klasse enthält für Vererbungsklassen Basiscode
ich über eine Schnittstelle denken würde, wenn das Datenelement nur Ihre Klasse
beschreiben Ja, es ist möglich, Elementvariablen in einer abstrakten Basisklasse bereitzustellen, mit der Absicht, dass die Unterklassen diese Elemente verwenden, um eine konkrete Implementierung durchzuführen.
Hier ist ein konkretes Beispiel, mit einer Auto-Analogie, die wir alle lieben.
Lassen Sie uns sagen, dass wir Car
eine abstrakte Basisklasse machen, die Platzhalter für Räder, Fahrwerk hat, und ein Motor für die Unterklassen verwenden:
abstract class Car {
Wheels wheels
Chassis chassis
Engine engine
abstract void accelerate();
abstract void decelerate();
}
Nun, für eine Klasse, die Car
, die Mitglieder erweitert diese Membervariablen zu füllen sind bereits dort zu verwenden, so ist die Verantwortung einer Unterklasse:
class NiceCar extends Car {
Decoration decoration;
public NiceCar() {
wheels = new ChromeWheels();
chassis = new LightweightCompositeChassis();
engine = new LotsOfHorsepowerEngine();
decoration = new CoolRacingStripes();
}
void accelerate() {
engine.feedFuel();
}
void decelerate() {
wheels.applyBrakes();
}
}
wie zu sehen ist, die abstrakte Basisklasse kann für die Komponenten (Membervariablen) als Vorlage arbeiten s sollte ausgefüllt werden, um die volle Funktionalität einer Klasse zu erhalten. In diesem Fall stellt die Car
grundlegende Teile eines Autos bereit, die in einer konkreten Implementierung verwendet werden. NiceCar
verwendet diese Mitgliedsfelder und fügt einige für eigene Features hinzu, z. B. einen dekorativen Farbauftrag.
Ich vermute, dass Sie einen zu engen Kreis um Ihr Konzept einer abstrakten Basisklasse zeichnen.
Eine abstrakte Basisklasse (im Gegensatz zu einer reinen Schnittstelle) ist eine Klasse, die beabsichtigt, dass einige ihrer Funktionen von untergeordneten Klassen verwendet werden.Es wird daher einige Funktionalität zusammen mit Methoden haben, die dazu bestimmt sind, übergangen zu werden (der Schnittstellenteil). Es gibt keinen Grund, warum dieser Funktion keine Membervariablen zugeordnet werden sollten.
Viele Frameworks basieren auf Vererbung. Diese werden fast zwangsläufig abstrakte Klassen mit Member-Variablen haben. Zum Beispiel ist DirectShow das Multimedia-Streaming-Framework in Windows. Die Quellen, Encoder, Decoder usw. sind alle in so genannten "Filtern" implementiert. Es gibt Basisklassen für verschiedene Arten von Filtern. Jeder von ihnen wird Mitglied Variablen für die Upstream-und Downstream-Filter, die ausgehandelten Medientypen, etc.
Wenn es ein Zustand von allen geerbten Klassen verwendet wird, denke ich, es ist obligatorisch, um es in die Basisklasse zu verschieben. Auch wenn die Basis abstrakt ist. Ich denke, die meisten Leute, die in Refactoring sind, würde mir hier zustimmen.
Es kann mehrere Gründe geben, warum ein bestimmter Zustand in der Basis sein sollte. Reduzieren der Code-Duplizierung ist ein guter Grund genug.
Prost!
Edit: Bitte sagen Sie mir, warum Sie unten abstimmen, damit ich verbessern kann. Vielen Dank!
+1, um den Downvote zu kompensieren. Wenn der Status allen abgeleiteten Klassen gemeinsam ist, dann verschieben Sie ihn auf jeden Fall in die Basisklasse. –
Danke Dan. Dieser Downvote war einfach umwerfend :) – ralphtheninja
Wie andere erwähnt haben, fügt man Instanzfelder zu jeder Art von Klasse hinzu, wenn ein Zustand gespeichert werden soll. Dies gilt für abstrakte oder konkrete Klassen - es gibt keinen Unterschied.
Warum sollte es einen Unterschied machen? Schließlich ist eine abstrakte Klasse genau wie jede andere Klasse, außer dass sie nicht instanziiert werden kann, was Unterklassen usw. erfordert, um die Klasse zu vervollständigen.
- 1. Freundesfunktionen und statische Datenelemente
- 2. Abstrakte Basisklasse Definition
- 3. Allgemeintypeinschränkung neuer() und eine abstrakte Basisklasse
- 4. statische abstrakte Methoden in C++
- 5. django Admin nicht zeigt abstrakte Basisklasse Felder
- 6. ASMX Web Service nicht serialisiert abstrakte Basisklasse
- 7. Abstrakte Basisklasse oder Schnittstelle? Weder scheint Recht
- 8. Sollte eine abstrakte Klasse mindestens eine abstrakte Methode haben?
- 9. Polymorphismus und private Datenelemente
- 10. Statische abstrakte Objekte mit virtuellen Methoden
- 11. Kann eine abstrakte Klasse eine endgültige Methode haben?
- 12. Typoskript - Nicht abstrakte Methode in der Basisklasse nicht erkannt
- 13. Statische Assert, um statische Const-Klasse Datenelemente zu überprüfen?
- 14. Soll ich statische Datenelemente verwenden? (C++)
- 15. Python zu initialisieren (komplexe) statische Datenelemente
- 16. Einrichten eines Fremdschlüssels für eine abstrakte Basisklasse mit Django
- 17. Ein Zeiger auf abstrakte Template-Basisklasse?
- 18. Wann das abstrakte Fabrikmuster verwenden?
- 19. Zeiger auf eine nicht statische Datenelemente in VS2015 falsch Update 2
- 20. Wie Abstrakte Basisklasse in JavaScript erstellen, die nicht
- 21. Python 2.6, 3 abstrakte Basisklasse Missverständnis
- 22. virtuellen desctructor auf reine abstrakte Basisklasse
- 23. eine abstrakte Klasse mit der Basisklasse in Schnittstelle C#
- 24. Nicht sicher, wann eine abstrakte Eigenschaft zu verwenden ist und wann nicht
- 25. PHP: polymorphe abstrakte statische Methoden
- 26. Abstrakte Basisklasse: raise NotImplementedError() in `__init __. Py`?
- 27. Wann statische Eigenschaft deklarieren?
- 28. Xcode 6: Kann eine statische iOS-Bibliothek eine Modulzuordnung haben?
- 29. Statische Methoden: Wann und wenn nicht
- 30. Kann nicht statisch abstrakte String-Eigenschaft definiert
Einverstanden. Datenelemente in abstrakten Klassen speichern Programmierer davon, sie mehrfach zu implementieren und stellen einen einzigen Typ bereit, über den sie zugänglich sind;) –
Nachdem ich über das Vorlagenmethodenmuster gelesen habe, denke ich, dass dies ein wirklich guter Grund ist. Ich habe von vielen "großen" C++ - Büchern gelesen, dass ABC's keine Daten haben sollten, also habe ich mich gefragt, ob es eine Ausnahme gibt. – rlbond