È possibile ma non come l'hai fatto tu.
Devi aggiungere un costruttore senza argomenti alla classe base e il gioco è fatto!
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";
}
}
Quando non aggiungi un costruttore (qualsiasi) a una classe, il compilatore aggiunge il costruttore predefinito no arg per te.
Quando il defualt no arg chiama super (); e poiché non lo hai nella super classe, ricevi quel messaggio di errore.
Si tratta della domanda in sé.
Ora, espandendo la risposta:
Sei consapevole che la creazione di una sottoclasse (comportamento) per specificare diverso un diverso valore (dati) non ha senso ?? !!! Spero che tu lo faccia.
Se l'unica cosa che cambia è il "nome" allora è sufficiente una sola classe parametrizzata!
Quindi non hai bisogno di questo:
MyClass a = new A("A");
MyClass b = new B("B");
MyClass c = new C("C");
MyClass d = new D("D");
o
MyClass a = new A(); // internally setting "A" "B", "C" etc.
MyClass b = new B();
MyClass c = new C();
MyClass d = new D();
Quando puoi scrivere questo:
MyClass a = new MyClass("A");
MyClass b = new MyClass("B");
MyClass c = new MyClass("C");
MyClass d = new MyClass("D");
Se dovessi cambiare la firma del metodo del costruttore BaseClass, dovrei cambiare tutte le sottoclassi.
Ecco perché l'ereditarietà è l'artefatto che crea accoppiamento ALTO, che è indesiderabile nei sistemi OO. Dovrebbe essere evitato e forse sostituito con la composizione.
Pensa se davvero ne hai davvero bisogno come sottoclasse. Ecco perché vedi molto spesso le interfacce utilizzate invece:
public interface NameAware {
public String getName();
}
class A implements NameAware ...
class B implements NameAware ...
class C ... etc.
Qui B e C potrebbero aver ereditato da A che avrebbe creato un accoppiamento molto ALTO tra loro, utilizzando interfacce l'accoppiamento è ridotto, se A decide che non sarà più "NameAware" le altre classi non si rompono.
Ovviamente, se vuoi riutilizzare il comportamento, questo non funzionerà.