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!
public abstract class A {
private String name;
public A(){
this.name = getName();
}
public abstract String getName();
public String toString(){
return "simple class name: " + this.getClass().getSimpleName() + " name:\"" + this.name + "\"";
}
}
class B extends A {
public String getName(){
return "my name is B";
}
public static void main( String [] args ) {
System.out.println( new C() );
}
}
class C extends A {
public String getName() {
return "Zee";
}
}
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:
MyClass a = new A("A");
MyClass b = new B("B");
MyClass c = new C("C");
MyClass d = new D("D");
oder
MyClass a = new A(); // internally setting "A" "B", "C" etc.
MyClass b = new B();
MyClass c = new C();
MyClass d = new D();
Wenn Sie dies schreiben können:
MyClass a = new MyClass("A");
MyClass b = new MyClass("B");
MyClass c = new MyClass("C");
MyClass d = new MyClass("D");
Wenn ich die Methodensignatur des BaseClass-Konstruktors ändern würde, müsste ich alle Unterklassen ändern.
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:
public interface NameAware {
public String getName();
}
class A implements NameAware ...
class B implements NameAware ...
class C ... etc.
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.