2011-06-06 11 views
11

Mientras estudiaba para mi final, encontré la siguiente declaración en el libro del que estoy estudiando. Teniendo en cuenta el siguiente código:Herencia de Java - constructores

class A { 
    public A(int x) { } 
} 

class B extends A { 
    public B(int x) { } 
} 

es obligatorio para llamar al constructor de la clase A en el constructor de la clase B (super (x)). El libro declara que no es obligatorio, porque tienen el número exacto y el tipo de parámetros. Pero cuando intento esto en un compilador de Java, el siguiente error se tira:

constructor de A en la clase A no puede ser aplicado a tipos dados; requerido: int encontrado: no hay argumentos razón: listas de argumentos reales y formales difieren en longitud

+2

El libro está mal. – Bohemian

Respuesta

17

El compilador inserta automáticamente super() en el principio.

Sin embargo, incluso los argumentos de los constructores, super() (sin argumentos) se agrega que invoca el predeterminado constructor de la superclase. Y no tienes uno, de ahí el error.

Debe especificar super(x) (para invocar A(x)) o definir un constructor sin argumento.

Por cierto, Eclipse compilador da una mejor manera mensaje de error:

implícito súper constructor de A() es indefinido. Debe invocar explícitamente a otro constructor

+0

El error se genera en esta línea: "public B (int x) {}". El código que publiqué en la pregunta es todo el código que estoy tratando de compilar (solo la definición de la clase, no hay instancias en absoluto). –

+0

Solo insertará 'super()'. No insertará 'super (int)'. De ahí el error aquí. En este caso, él necesita llamar 'super (x)'. Ver http://download.oracle.com/javase/tutorial/java/IandI/super.html. – MGwynne

+0

@MGwynne sí, recién actualizado – Bozho

1

Esto sucede cuando no tiene un constructor predeterminado y está creando una instancia con uno predeterminado. Porque si tiene cualquier constructor parametrizado, el compilador no insertará el predeterminado para usted, en su lugar debe definirlo.

4

Parece que el compilador intenta crear una llamada al constructor por defecto con superclases super(), que no está disponible:

required: int 
found: no arguments 

Pero volviendo a su libro: nunca he oído hablar de una norma que Puede omitir la instrucción super en un constructor si el constructor real tiene exactamente la misma lista de parámetros que un constructor en la superclase directa. Solo se agrega implícitamente una llamada al constructor predeterminado de la superclase (super()) pero eso requiere que la superclase tenga como constructor predeterminado.

A diferencia de lo que está escrito en su libro (o en contraste con su comprensión del texto escrito), he aquí una frase de la especificación de lenguaje:

Si un cuerpo del constructor no comienza con un constructor explícito invocación y el constructor de ser declarado no es parte de la clase de objeto primordial, entonces el cuerpo del constructor se asume implícitamente por el compilador para comenzar con una super clase invocación del constructor “super();”, una invocación del constructor de su superclase directa que no toma partido nts.

4

Si usted tiene una clase de la base que tiene un constructor por defecto (constructor sin argumentos), cuando extiende B, no es necesario llamar explícitamente super() porque es llamado de ninguna manera.

Pero cuando se tiene un constructor con argumentos, al hacer el contructor con los parámetros de B, tiene que pasar en super() un parámetro para A

ejemplo:

class A { 
    public A(int x) { } 
    } 

    class B extends A { 
    public B(int x) 
    { 
     super(x); // need to specify the parameter for class A 
     //... 
    } 
    } 
0

Es neccessary llamar al constructor de superclase en el caso de Java. Por lo tanto, cada vez que genere el constructor de la subclase, IDE creará el constructor de la superclase.

Es porque cada vez que el constructor de la clase base exige argumentos, el compilador cree que deben ser llenados por el constructor de la clase base. En el caso de un constructor predeterminado, está bien. No es necesario llamar a super() en la subclase.