Ich habe einen einfachen Java-Code, der in seiner Struktur ähnlich aussieht:
abstract public class BaseClass {
String someString;
public BaseClass(String someString) {
this.someString = someString;
}
abstract public String getName();
}
public class ACSubClass extends BaseClass {
public ASubClass(String someString) {
super(someString);
}
public String getName() {
return "name value for ASubClass";
}
}
Ich werde einige Unterklassen von haben BaseClass
, von denen jede die getName()
Methode auf ihre eigene Weise implementiert ( Muster der Vorlagenmethode ).
Das funktioniert gut, aber ich mag es nicht, den redundanten Konstruktor in den Unterklassen zu haben. Es ist mehr zu tippen und es ist schwierig zu pflegen. Wenn ich die Methodensignatur des BaseClass
Konstruktors ändern würde, müsste ich alle Unterklassen ändern.
Wenn ich den Konstruktor aus den Unterklassen entferne, wird der folgende Fehler zur Kompilierungszeit angezeigt:
Implicit super constructor BaseClass() is undefined for default constructor. Must define an explicit constructor
Ist das, was ich versuche, möglich?
quelle
Antworten:
Sie erhalten diesen Fehler, weil eine Klasse ohne Konstruktor einen Standardkonstruktor hat , der ohne Argumente ist und dem folgenden Code entspricht:
Da Ihre BaseClass jedoch einen Konstruktor deklariert (und daher nicht den Standardkonstruktor
super();
ohne Argumente hat , den der Compiler sonst bereitstellen würde), ist dies unzulässig - eine Klasse, die BaseClass erweitert, kann nicht aufgerufen werden, da es keinen Konstruktor ohne Argumente gibt in BaseClass.Dies ist wahrscheinlich ein wenig kontraintuitiv, da Sie vielleicht denken, dass eine Unterklasse automatisch einen Konstruktor hat, über den die Basisklasse verfügt.
Der einfachste Weg, dies zu umgehen, besteht darin, dass die Basisklasse keinen Konstruktor deklariert (und daher den Standardkonstruktor no-arg hat) oder einen deklarierten Konstruktor no-arg hat (entweder für sich oder zusammen mit anderen Konstruktoren). Oft kann dieser Ansatz jedoch nicht angewendet werden, da Sie alle Argumente benötigen, die an den Konstruktor übergeben werden, um eine legitime Instanz der Klasse zu erstellen.
quelle
BaseClass
aber lassen Sie ihn einfach einenUnsupportedOperationException
oder etwas werfen . Es ist nicht die beste Lösung (es deutet fälschlicherweise darauf hin, dass die Klasse einen Konstruktor ohne Argumente unterstützen kann), aber es ist die beste, die ich mir vorstellen kann.Für diejenigen, die nach diesem Fehler suchen und hier ankommen: Es kann einen anderen Grund geben, ihn zu erhalten. Eclipse gibt diesen Fehler aus, wenn Sie ein Projekt-Setup haben - die Systemkonfiguration stimmt nicht überein.
Wenn Sie beispielsweise ein Java 1.7-Projekt in Eclipse importieren und 1.7 nicht richtig eingerichtet haben, wird dieser Fehler angezeigt. Dann können Sie entweder zu
Project - Preference - Java - Compiler
und gehenswitch to 1.6 or earlier
; oder gehen Sie zuWindow - Preferences - Java - Installed JREs
und fügen Sie Ihre JRE 1.7-Installation hinzu / reparieren Sie sie.quelle
Es ist möglich, aber nicht so, wie Sie es haben.
Sie müssen der Basisklasse einen Konstruktor ohne Argumente hinzufügen, und das war's!
Wenn Sie einer Klasse keinen Konstruktor (any) hinzufügen, fügt der Compiler den Standard-Konstruktor no arg für Sie hinzu.
Wenn das Defualt no arg zu super () aufruft; und da Sie es nicht in der Superklasse haben, erhalten Sie diese Fehlermeldung.
Das ist über die Frage selbst.
Erweitern Sie nun die Antwort:
Ist Ihnen bewusst, dass das Erstellen einer Unterklasse (Verhalten) zur Angabe eines anderen Wertes (Daten) keinen Sinn macht? !!! Ich hoffe du tust.
Wenn sich nur der "Name" ändert, reicht eine einzige parametrisierte Klasse aus!
Das brauchst du also nicht:
oder
Wenn Sie dies schreiben können:
Deshalb ist Vererbung das Artefakt, das eine HOHE Kopplung erzeugt, was in OO-Systemen unerwünscht ist. Es sollte vermieden und vielleicht durch Komposition ersetzt werden.
Überlegen Sie, ob Sie sie wirklich wirklich als Unterklasse brauchen. Deshalb sehen Sie sehr oft verwendete Schnittstellen insted:
Hier könnten B und C von A geerbt haben, was eine sehr hohe Kopplung zwischen ihnen erzeugt hätte. Durch die Verwendung von Schnittstellen wird die Kopplung reduziert, wenn A entscheidet, dass es nicht mehr "NameAware" ist, werden die anderen Klassen nicht kaputt gehen.
Wenn Sie das Verhalten wiederverwenden möchten, funktioniert dies natürlich nicht.
quelle
Sie können diesen Fehler auch erhalten, wenn JRE nicht festgelegt ist. Versuchen Sie in diesem Fall , Ihrem Projekt die JRE-Systembibliothek hinzuzufügen .
Unter Eclipse IDE:
quelle
Eine andere Möglichkeit besteht darin, super () mit dem erforderlichen Argument als erste Anweisung im abgeleiteten Klassenkonstruktor aufzurufen.
quelle
Eclipse gibt diesen Fehler aus, wenn Sie den Superklassenkonstruktor nicht als erste Anweisung im Unterklassenkonstruktor aufrufen.
quelle
Entschuldigen Sie die Nekropostierung, aber ich bin erst heute mit diesem Problem konfrontiert. Für alle, die ebenfalls mit diesem Problem konfrontiert sind - einer der möglichen Gründe -, rufen Sie nicht
super
in der ersten Zeile der Methode auf. Zweite, dritte und andere Zeilen lösen diesen Fehler aus. Call of Super sollte der allererste Aufruf in Ihrer Methode sein. In diesem Fall ist alles in Ordnung.quelle
Sie können diesen Fehler beheben, indem Sie der Basisklasse einen argumentlosen Konstruktor hinzufügen (siehe Abbildung unten).
Prost.
quelle
someString
) zu konstruieren , und macht somit den Zweck als Konstruktor völlig zunichte.Ich hatte diesen Fehler und habe ihn behoben, indem ich eine ausgelöste Ausnahme neben der Methode in einen Try / Catch-Block entfernt habe
Zum Beispiel: FROM:
ZU:
quelle