Jest to możliwe, ale nie tak, jak masz.
Musisz dodać konstruktor no-args do klasy bazowej i to wszystko!
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";
}
}
Gdy nie dodasz konstruktora (żadnego) do klasy, kompilator doda domyślny konstruktor no arg.
Gdy defualt no arg wywołuje super (); a ponieważ nie masz go w super klasie, otrzymasz ten komunikat o błędzie.
Chodzi o samo pytanie.
Teraz rozszerzając odpowiedź:
Czy zdajesz sobie sprawę, że tworzenie podklasy (zachowania) w celu określenia innej wartości (danych) nie ma sensu ?? !!! Mam nadzieję, że tak.
Jeśli jedyną zmianą jest "nazwa", to wystarczy jedna sparametryzowana klasa!
Więc nie potrzebujesz tego:
MyClass a = new A("A");
MyClass b = new B("B");
MyClass c = new C("C");
MyClass d = new D("D");
lub
MyClass a = new A();
MyClass b = new B();
MyClass c = new C();
MyClass d = new D();
Kiedy możesz to napisać:
MyClass a = new MyClass("A");
MyClass b = new MyClass("B");
MyClass c = new MyClass("C");
MyClass d = new MyClass("D");
Gdybym miał zmienić sygnaturę metody konstruktora BaseClass, musiałbym zmienić wszystkie podklasy.
Cóż, dlatego dziedziczenie jest artefaktem, który tworzy WYSOKIE sprzężenie, co jest niepożądane w systemach OO. Należy tego unikać i być może zastąpić kompozycją.
Pomyśl, czy naprawdę potrzebujesz ich jako podklasy. Dlatego bardzo często widzisz interfejsy używane zamiast:
public interface NameAware {
public String getName();
}
class A implements NameAware ...
class B implements NameAware ...
class C ... etc.
Tutaj B i C mogliby odziedziczyć po A, co stworzyłoby wśród nich bardzo WYSOKIE sprzężenie, przy użyciu interfejsów sprzężenie jest zredukowane, jeśli A zdecyduje, że nie będzie już „NameAware”, inne klasy nie zostaną zerwane.
Oczywiście, jeśli chcesz ponownie użyć zachowania, to nie zadziała.