java inheritance dry boilerplate

Error de Java: el superconstructor implícito no está definido para el constructor predeterminado



inheritance dry (10)

Tengo un código Java simple que se parece a esto en su estructura:

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"; } }

Tendré bastantes subclases de BaseClass , cada una implementando el método getName() a su manera ( patrón de método de plantilla ).

Esto funciona bien, pero no me gusta tener el constructor redundante en las subclases. Es más para escribir y es difícil de mantener. Si BaseClass que cambiar la firma del método del constructor BaseClass , tendría que cambiar todas las subclases.

Cuando elimino el constructor de las subclases, obtengo este error en tiempo de compilación:

Implicit super constructor BaseClass() is undefined for default constructor. Must define an explicit constructor

¿Es lo que estoy tratando de hacer posible?


Eclipse dará este error si no tiene una llamada al constructor de la clase superior como una primera instrucción en el constructor de la subclase.


Es posible pero no de la manera que lo tienes.

¡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 contructor no arg por defecto para usted.

Cuando el defualt no arg llama a super (); y como no lo tienes en la súper clase, recibes ese mensaje de error.

Esa es la pregunta en sí misma.

Ahora, expandiendo la respuesta:

¿Sabía que crear una subclase (comportamiento) para especificar un valor diferente (datos) no tiene sentido? Espero que lo hagas.

¡Si lo único que cambia es el "nombre", entonces 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(); // internally setting "A" "B", "C" etc. 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, esa es la razón por la cual la herencia es el artefacto que crea un acoplamiento ALTO, lo cual es indeseable en los sistemas OO. Debe evitarse y tal vez reemplazarse con la composición.

Piensa si realmente los necesitas como subclase. Es por eso que usted ve muy a menudo las interfaces utilizadas insted:

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 quiere reutilizar el comportamiento, esto no funcionará.


Lo siento por necroposting, pero se enfrentó a este problema solo hoy. Para todos los que también enfrentan este problema, uno de los posibles motivos, no llaman a super en la primera línea de método. La segunda, la tercera y otras líneas activan este error. Call of super debería ser la primera llamada en tu método. En este caso, todo está bien.


Obtiene este error porque una clase que no tiene constructor tiene un constructor predeterminado , que no tiene argumento y es equivalente al siguiente código:

public ACSubClass() { super(); }

Sin embargo, dado que su BaseClass declara un constructor (y, por lo tanto, no tiene el constructor predeterminado arg que el compilador proporcionaría), esto es ilegal: una clase que amplía BaseClass no puede llamar a super(); porque no hay un constructor sin argumentos en BaseClass.

Esto es probablemente un poco contra-intuitivo porque podría pensar que una subclase tiene automáticamente cualquier constructor que tenga la clase base.

La forma más sencilla de evitar esto es que la clase base no declare un constructor (y por lo tanto tenga el constructor predeterminado no-arg) o tenga un constructor no-arg declarado (ya sea solo o junto a cualquier otro constructor). Pero a menudo este enfoque no se puede aplicar, porque necesita que se pasen los argumentos al constructor para construir una instancia legítima de la clase.


Otra forma es llamar a super () con el argumento requerido como una primera instrucción en el constructor de clase derivado.

public class Sup { public Sup(String s) { ...} } public class Sub extends Sup { public Sub() { super("hello"); .. } }


Para aquellos que buscan este error y llegan aquí: puede haber otra razón para recibirlo. Eclipse proporciona este error cuando tiene la configuración del proyecto: la configuración del sistema no coincide.

Por ejemplo, si importa el proyecto Java 1.7 a Eclipse y no tiene 1.7 configurado correctamente, obtendrá este error. Luego puede ir a Project - Preference - Java - Compiler y switch to 1.6 or earlier ; o vaya a Window - Preferences - Java - Installed JREs y agregue / corrija su instalación de JRE 1.7.


Puede resolver este error agregando un constructor sin argumento a la clase base (como se muestra a continuación).

Aclamaciones.

abstract public class BaseClass { // ADD AN ARGUMENTLESS CONSTRUCTOR TO THE BASE CLASS public 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"; } }


También podría obtener este error cuando JRE no esté configurado. Si es así, intente agregar JRE System Library a su proyecto.

En Eclipse IDE:

  1. abra el menú Proyecto -> Propiedades , o haga clic derecho en su proyecto en el Explorador de paquetes y elija Propiedades (Alt + Intro en Windows, Comando + I en Mac)
  2. haga clic en la ruta de compilación de Java y luego en la pestaña Bibliotecas
  3. elija Modulepath o Classpath y presione el botón Agregar biblioteca ...
  4. seleccione la Biblioteca del sistema JRE y luego haga clic en Siguiente
  5. mantenga el JRE predeterminado de Workspace seleccionado (también puede tomar otra opción) y haga clic en Finalizar
  6. finalmente presione Aplicar y Cerrar .

Tuve este error y lo solucioné eliminando una excepción lanzada desde al lado del método a un bloque try / catch

Por ejemplo: FROM:

public static HashMap<String, String> getMap() throws SQLException { }

A:

public static Hashmap<String,String> getMap() { try{ }catch(SQLException) { } }


su BaseClass necesita un SomeString así que entregue uno.
Prueba esto:

abstract public class BaseClass { String someString; public BaseClass(String someString) { this.someString = someString; } abstract public String getName(); } public class ACSubClass extends BaseClass { public ASubClass() { super("someString"); // or a meaningfull value, same as getName()? } public String getName() { return "name value for ASubClass"; } }

o

abstract public class BaseClass { String someString; protected BaseClass() { // for subclasses this.someString = null; // or a meaningfull value } public BaseClass(String someString) { this.someString = someString; } abstract public String getName(); } public class ACSubClass extends BaseClass { public String getName() { return "name value for ASubClass"; } }