Es posible, pero no de la forma en que lo tiene.
¡Tienes que agregar un constructor sin argumentos a la clase base y eso es todo!
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";
}
}
Cuando no agrega un constructor (cualquiera) a una clase, el compilador agrega el constructor predeterminado sin arg para usted.
Cuando el defualt no arg llama a super (); y como no lo tiene en la superclase, aparece ese mensaje de error.
Esa es la pregunta en sí misma.
Ahora, ampliando la respuesta:
¿Es consciente de que crear una subclase (comportamiento) para especificar un valor (datos) diferente no tiene sentido? Espero que lo hagas.
Si lo único que cambia es el "nombre", ¡una sola clase parametrizada es suficiente!
Entonces no necesitas esto:
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();
MyClass b = new B();
MyClass c = new C();
MyClass d = new D();
Cuando puedes escribir esto:
MyClass a = new MyClass("A");
MyClass b = new MyClass("B");
MyClass c = new MyClass("C");
MyClass d = new MyClass("D");
Si tuviera que cambiar la firma del método del constructor BaseClass, tendría que cambiar todas las subclases.
Bueno, es por eso que la herencia es el artefacto que crea un acoplamiento ALTO, lo cual no es deseable en los sistemas OO. Debería evitarse y quizás reemplazarse con composición.
Piense si realmente los necesita como subclase. Es por eso que ve muy a menudo que se usan interfaces en:
public interface NameAware {
public String getName();
}
class A implements NameAware ...
class B implements NameAware ...
class C ... etc.
Aquí B y C podrían haber heredado de A lo que habría creado un acoplamiento muy ALTO entre ellos, al usar interfaces el acoplamiento se reduce, si A decide que ya no será "NameAware", las otras clases no se romperán.
Por supuesto, si desea reutilizar el comportamiento, esto no funcionará.