Warum können Java-Klassen keine abstrakten Felder haben, wie sie abstrakte Methoden haben können?
Zum Beispiel: Ich habe zwei Klassen, die dieselbe abstrakte Basisklasse erweitern. Diese beiden Klassen haben jeweils eine identische Methode, mit Ausnahme einer String-Konstante, die zufällig eine Fehlermeldung enthält. Wenn Felder abstrakt sein könnten, könnte ich diese Konstante abstrakt machen und die Methode in die Basisklasse hochziehen. Stattdessen muss ich eine abstrakte Methode erstellen, die getErrMsg()
in diesem Fall aufgerufen wird, die den String zurückgibt, diese Methode in den beiden abgeleiteten Klassen überschreiben und dann die Methode aufrufen (die jetzt die abstrakte Methode aufruft).
Warum konnte ich das Feld nicht gleich abstrakt machen? Könnte Java entwickelt worden sein, um dies zu ermöglichen?
Antworten:
Sie können das tun, was Sie beschrieben haben, indem Sie ein letztes Feld in Ihrer abstrakten Klasse haben, das in ihrem Konstruktor initialisiert ist (nicht getesteter Code):
Wenn Ihre untergeordnete Klasse "vergisst", das Finale über den Superkonstruktor zu initialisieren, gibt der Compiler
eine Warnungeinen Fehler aus, genau wie wenn eine abstrakte Methode nicht implementiert ist.quelle
Base
, es muss deklariert werdenabstract
.Darin sehe ich keinen Sinn. Sie können die Funktion in die abstrakte Klasse verschieben und einfach ein geschütztes Feld überschreiben. Ich weiß nicht, ob dies mit Konstanten funktioniert, aber der Effekt ist der gleiche:
Ihr Punkt ist also, dass Sie die Implementierung / Überschreiben / was auch immer
errorMsg
in den Unterklassen erzwingen möchten ? Ich dachte, Sie wollten nur die Methode in der Basisklasse haben und wussten damals nicht, wie Sie mit dem Feld umgehen sollten.quelle
protected String errorMsg;
was irgendwie erzwingt, dass ich den Wert in den Unterklassen setze. Es ähnelt den abstrakten Klassen, die tatsächlich alle Methoden als Platzhalter implementieren, sodass Entwickler nicht jede Methode implementieren müssen, obwohl sie sie nicht benötigen.protected String errorMsg;
wird nicht erzwungen, dass Sie den Wert in Unterklassen festlegen.Natürlich hätte es dies ermöglichen können, aber unter dem Deckmantel müsste es immer noch einen dynamischen Versand und damit einen Methodenaufruf durchführen. Javas Design (zumindest in den frühen Tagen) war bis zu einem gewissen Grad ein Versuch, minimalistisch zu sein. Das heißt, die Designer haben versucht, das Hinzufügen neuer Funktionen zu vermeiden, wenn sie durch andere Funktionen, die bereits in der Sprache vorhanden sind, problemlos simuliert werden können.
quelle
Als ich Ihren Titel las, dachte ich, Sie beziehen sich auf abstrakte Instanzmitglieder. und ich konnte nicht viel Verwendung für sie sehen. Aber abstrakte statische Elemente sind eine ganz andere Sache.
Ich habe mir oft gewünscht, dass ich eine Methode wie die folgende in Java deklarieren könnte:
Grundsätzlich möchte ich darauf bestehen, dass konkrete Implementierungen meiner übergeordneten Klasse eine statische Factory-Methode mit einer bestimmten Signatur bereitstellen. Dies würde es mir ermöglichen, einen Verweis auf eine konkrete Klasse mit zu erhalten
Class.forName()
und sicher zu sein, dass ich eine in einer Konvention meiner Wahl konstruieren könnte.quelle
@autowired T fieldName
. Wenn dies als "Typ löschen"T
definiert istT extends AbstractController
, wird das Feld als TypAbstractController
gelöscht und kann nicht automatisch verdrahtet werden, da es nicht konkret und nicht eindeutig ist. Ich stimme im Allgemeinen zu, dass sie nicht viel nützen und daher nicht in die Sprache gehören. Was ich nicht zustimmen würde, ist, dass es KEINE Verwendung für sie gibt.Eine andere Möglichkeit besteht darin, das Feld in der Basisklasse als öffentlich (endgültig, wenn Sie möchten) zu definieren und dieses Feld dann im Konstruktor der Basisklasse zu initialisieren, je nachdem, welche Unterklasse derzeit verwendet wird. Es ist ein bisschen zwielichtig, da es eine zirkuläre Abhängigkeit einführt. Aber zumindest ist es keine Abhängigkeit, die sich jemals ändern kann - dh die Unterklasse wird entweder existieren oder nicht existieren, aber die Methoden oder Felder der Unterklasse können den Wert von nicht beeinflussen
field
.quelle