¿Por qué se requiere el constructor predeterminado en una clase padre si tiene un constructor argumento-ed?

Por qué se requiere el constructor predeterminado (explícitamente) en una clase padre si tiene un constructor argumentado

class A { A(int i){ } } class B extends A { } class Main { public static void main(String a[]){ B b_obj = new B(); } } 

Esto será un error.

Aquí hay dos aspectos en juego:

  • Si especifica un constructor explícitamente (como en A ), el comstackdor de Java no creará un constructor sin parámetros para usted.

  • Si no especifica un constructor explícitamente (como en B ), el comstackdor de Java creará un constructor sin parámetros para usted de la siguiente manera:

     B() { super(); } 

(La accesibilidad depende de la accesibilidad de la clase en sí).

Eso es intentar llamar al constructor sin parámetros de la superclase, por lo que debe existir. Tienes dos opciones:

  • Proporcionar un constructor sin parámetros explícitamente en A
  • Proporcione un constructor sin parámetros explícitamente en B que llama explícitamente al constructor de la clase base con un argumento int apropiado.

Por qué se requiere el constructor predeterminado (explícitamente) en una clase padre si tiene un constructor argumentado

Yo diría que esta afirmación no siempre es correcta. Como idealmente no es requerido .

La regla es: si está proporcionando explícitamente un constructer argumento-ed, entonces el constructor predeterminado (no argumentado) no está disponible para la clase.

 For Example : class A { A(int i){ } } class B extends A { } 

Entonces cuando escribes

 B obj_b = new B(); 

En realidad, llama al constructor implícito proporcionado por Java a B, que de nuevo llama al super (), que idealmente debería ser A (). Pero como ha proporcionado el constructor argument-ed a A, el constructor predeterminado i: e A () no está disponible para B ().

Esa es la razón por la que necesita que A () se declare específicamente para que B () llame a super ().

Suponiendo que quisiste escribir la class B extends A :

Cada constructor tiene que llamar a un constructor de superclase; si no lo hace, el constructor de la superclase sin parámetros se llama implícitamente.

Si (y solo si) una clase no declara ningún constructor, el comstackdor de Java le otorga un constructor predeterminado que no toma parámetros y llama al constructor sin parámetros de la superclase. En su ejemplo, A declara un constructor y, por lo tanto, no tiene dicho constructor predeterminado. La clase B no declara un constructor, pero no puede obtener un constructor predeterminado porque su superclase no tiene un constructor sin parámetros para llamar. Como una clase siempre debe tener un constructor, este es un error del comstackdor.

Cada constructor de subclase llama al constructor predeterminado de la superclase, si el constructor de la subclase no llama explícitamente a otro constructor de la superclase. Por lo tanto, si su constructor de subclase llama explícitamente a un constructor de superclase que proporcionó (con argumentos), entonces no hay necesidad de ningún constructor de argumentos en la superclase. Entonces, lo siguiente comstackrá:

 class B extends A{ B(int m){ super(m); } } 

Pero lo siguiente no se comstackrá, a menos que proporcione explícitamente ningún constructor args en la superclase:

 class B extends A{ int i; B(int m){ i=m; } } 
 Why default constructor is required(explicitly) in a parent class if it has an argumented constructor 

¡No necesariamente!

Ahora en tu clase B

 class B extends A { } 

no ha proporcionado ningún constructor en la Clase B por lo que se colocará un constructor predeterminado. Ahora es una regla que cada constructor debe llamar a uno de sus constructores de clase superior. En su caso, el constructor predeterminado en la Clase B intentará llamar al constructor predeterminado en la clase A (es padre) pero como no tiene un constructor predeterminado en la Clase A (ya que ha proporcionado explícitamente un constructor con argumentos en la clase A, lo hará no tiene un constructor predeterminado en la Clase A) obtendrá un error.

Lo que podrías hacer es

O bien no proporcione ningún constructor args en la clase A.

 A() { //no arg default constructor in Class A } 

O

Escriba explícitamente no args constructor en B y llame a su súper con algún argumento int predeterminado.

 B() { super(defaultIntValue); } 

En pocas palabras, para que se cree un objeto, se deben invocar por completo los constructores de cada padre en la jerarquía de herencia. A cuáles llamar es realmente su elección de diseño. Pero en caso de que no proporcione explícitamente ningún java, pondrá la llamada de constructor predeterminada super () como primera línea de cada uno de los constructores de su clase secundaria y, si no tiene eso en la superclase, obtendrá un error.

Hay algunas cosas que deben tenerse en cuenta al usar constructores y cómo debe declararlos en su clase base y súper clase. Esto puede ser un poco confuso únicamente porque puede haber muchas posibilidades de disponibilidad o existencia de constructores en la super clase o clase base. Trataré de ahondar en todas las posibilidades:

  • Si define explícitamente constructores en cualquier clase (clase base / superclase), el comstackdor Java no creará ningún constructor para usted en esa clase respectiva.

  • Si no define explícitamente constructores en cualquier clase (clase base / superclase), el comstackdor Java creará un constructor sin argumentos para usted en esa clase respectiva.

  • Si su clase es una clase base que hereda de una superclase y no define explícitamente constructores en esa clase base, el comstackdor no solo creará un constructor sin argumentos (como el punto anterior), sino que también llamará implícitamente al constructor sin argumentos de la superclase.

     class A { A() { super(); } } 
  • Ahora bien, si no especifica explicity tipo super (), (o super (parámetros)), el comstackdor incluirá el super () para usted en su código.
  • Si el comstackdor llama a super () (explícita o implícitamente), el comstackdor esperará que su superclase tenga un constructor sin parámetros. Si no encuentra ningún constructor en su superclase sin parámetros, le dará un error de comstackción.

  • De manera similar, si se llama a super (parámetros), el comstackdor esperará que su superclase tenga un constructor con parámetros (el número y tipo de parámetros deben coincidir). Si no encuentra dicho constructor en su superclase, le dará un error de comstackción. (El comstackdor nunca puede invocar implícitamente a los Súper (parámetros). Tiene que incluirse explícitamente en su código, si es necesario).

Podemos resumir algunas cosas de las reglas anteriores

  • Si su superclase solo tiene un constructor con parámetros y no tiene un constructor sin argumentos, debe tener una statement super (parámetros) explícita en su constructor. Esto se debe a que si no haces eso, una sentencia super () se incluirá implícitamente en tu código y, dado que tu superclase no tiene un constructor sin argumentos, mostrará un error de comstackción.
  • Si su superclase tiene un constructor con parámetros y otro constructor sin argumentos, no es necesario tener una statement super (parámetros) explícita en su constructor. Esto se debe a que el comstackdor colocará implícitamente una sentencia super () en tu código y, dado que tu superclase tiene un constructor sin argumentos, funcionará bien.
  • Si su superclase solo tiene un constructor sin argumentos, puede referirse al punto anterior ya que es lo mismo.

Otra cosa que debe tenerse en cuenta es si su superclase tiene un constructor privado, que creará un error cuando compile su subclase. Esto se debe a que si no escribe un constructor en su subclase, llamará al constructor de la superclase y el superinicio implícito intentará buscar un constructor sin argumentos en la superclase, pero no encontrará uno.

Digamos esto comstackdo, ¿qué esperas que imprima?

 class A{ A(int i){ System.out.println("Ai= "+i); } } class B extends A { public static void main(String... args) { new B(); } } 

Cuando se construye A, se debe pasar un valor para i , sin embargo, el comstackdor no sabe qué debería ser, por lo que se debe especificar explícitamente en un constructor (cualquier constructor, no tiene que ser uno por defecto)

Por supuesto es un error si se escribe así, no es JAVA.

Si hubiera utilizado la syntax JAVA, no sería un error.

Las clases A y B no saben nada sobre si están en archivos / paquetes separados.

La clase A no necesita un constructor predeterminado, funciona bien solo con un constructor de parámetros.

Si B extiende A, simplemente usa una llamada a super (int a) en el constructor de B y todo está bien. para los constructores que no llamen a un super (vacío / o no) que extienda una superclase, el comstackdor agregará una llamada a super ().

Para leer más, mira Usar la palabra clave súper

Supongo que es porque cuando tienes una lista de parámetros vacía, no se puede crear una instancia de la supervariable. Con la lista de parámetros vacía me refiero al súper implícito () que el comstackdor podría agregar si la superclase tuviera un constructor no paramétrico.

Por ejemplo, si escribe:

 int a; System.out.print(a); 

Obtendrá un error con lo que creo que es el mismo error de lógica.

Cuando tenemos el constructor de parámetros estamos explícitamente atados al consumidor por diseño. él no puede crear el objeto de esa clase sin parámetro. en algún momento debemos forzar al usuario a proporcionar valor. objeto debe crearse solo proporcionando el parámetro (valor predeterminado).

 class Asset { private int id; public Asset(int id) { this.id = id; } } class Program { static void Main(string[] args) { /* Gives Error - User can not create object. * Design bound */ Asset asset1 = new Asset();/* Error */ } } 

Incluso la clase infantil no puede crear. por lo tanto, es un comportamiento de buen diseño.