¿Por qué se invoca el constructor de superclase cuando declaramos el objeto de la subclase? (Java)

Considera este código:

class Test { Test() { System.out.println("In constructor of Superclass"); } int adds(int n1, int n2) { return(n1+n2); } void print(int sum) { System.out.println("the sums are " + sum); } } class Test1 extends Test { Test1(int n1, int n2) { System.out.println("In constructor of Subclass"); int sum = this.adds(n1,n2); this.print(sum); } public static void main(String[] args) { Test1 a=new Test1(13,12); Test c=new Test1(15,14); } } 

Si tenemos un constructor en super clase, será invocado por cada objeto que construyamos para la clase hija (por ejemplo, el Objeto ‘a’ para la clase Test1 llama a Prueba1 (int n1, int n2) así como a Prueba ()).

¿Por qué pasó esto?

El resultado de este progtwig es:

En constructor de Superclass

En constructor de Subclase

las sums son 25

En constructor de Superclass

En constructor de Subclase

las sums son 29

Porque asegurará que cuando se invoca un constructor, puede confiar en que se inicialicen todos los campos de su superclase.

ver 3.4.4 aquí

Sí. Se debe construir una superclase antes de que también se pueda construir una clase derivada; de lo contrario, algunos campos que deberían estar disponibles en la clase derivada podrían no inicializarse.

Una pequeña nota: si tiene que llamar explícitamente al constructor de la superclase para pasarle algunos parámetros:

 baseClassConstructor(){ super(someParams); } 

entonces el superconstructor debe ser la primera llamada al método en el constructor derivado. Por ejemplo, esto no comstackrá:

 baseClassConstructor(){ foo(); super(someParams); // comstacktion error } 

super () se agrega en cada constructor de clase automáticamente por comstackdor.

Como sabemos bien, el comstackdor proporciona automáticamente el constructor predeterminado, pero también agrega super () para la primera instrucción. Si está creando su propio constructor y no tiene this () o super () como primer enunciado, el comstackdor proporcionará super () como la primera statement del constructor .

enter image description here

Las clases de Java se instancian en el siguiente orden:

(en tiempo de carga de clases) 0. inicializadores para miembros estáticos y bloques de inicializadores estáticos, en orden de statement.

(en cada objeto nuevo)

  1. crear variables locales para argumentos de constructor
  2. si el constructor comienza con la invocación de otro constructor para la clase, evalúe los argumentos y recurse al paso anterior. Todos los pasos se completan para ese constructor, incluida la recursión adicional de llamadas al constructor, antes de continuar.
  3. si la superclase no ha sido construida por lo anterior, construya la superclase (utilizando el constructor no-arg si no se especifica). Como # 2, siga todos estos pasos para la superclase, incluida la construcción de la superclase de IT, antes de continuar.
  4. inicializadores para variables de instancia y bloques de inicializador no estáticos, en orden de statement.
  5. rest del constructor.

Así es como funciona Java. Si crea un objeto secundario, se llama (implícitamente) al superconstructor.

La subclase hereda campos de su (s) superclase (s) y esos campos tienen que ser construidos / inicializados (ese es el propósito habitual de un constructor: iniciar a los miembros de la clase para que la instancia funcione según sea necesario. Sabemos que algunas personas pero mucha más funcionalidad en esos pobres constructores …)

Constructor implementa lógica que hace que el objeto esté listo para funcionar. Object puede contener estado en campos privados, por lo que solo los métodos de su clase pueden acceder a ellos. Entonces, si desea que la instancia de su subclase esté realmente lista para funcionar después de llamar al constructor (es decir, todas sus funcionalidades, incluida la heredada de la clase base, está bien), se debe llamar al constructor de la clase base.

Esta es la razón por la cual el sistema funciona de esta manera.

Automáticamente se llama al constructor predeterminado de la clase base. Si desea cambiar esto, debe llamar explícitamente al constructor de la clase base escribiendo super() en la primera línea del constructor de su subclase.

Se llamará al constructor de la clase base antes del constructor de la clase derivada. Esto tiene sentido porque garantiza que la clase base está construida correctamente cuando se ejecuta el constructor para la clase derivada. Esto le permite utilizar algunos de los datos de la clase base durante la construcción de la clase derivada.

Cuando creamos un objeto de subclase, debe tener en cuenta todas las funciones de miembro y las variables de miembro definidas en la superclase. Puede surgir un caso en el que una variable miembro pueda inicializarse en algunos de los constructores de superclase. Por lo tanto, cuando creamos un objeto de subclase, todos los constructores en el árbol de herencia correspondiente se llaman en la parte superior-inferior.

Específicamente, cuando una variable se define como protegida , siempre estará accesible en la subclase, independientemente de si la subclase está en el mismo paquete o no . Ahora, desde la subclase, si llamamos a una función de superclase para imprimir el valor de esta variable protegida (que puede inicializarse en el constructor de la superclase) debemos obtener el valor inicializado correcto. Por lo tanto, todos los constructores de superclase se invocan.

Internamente Java llama a super () en cada constructor. Por lo tanto, cada constructor de subclase lo llama constructor de superclase utilizando super () y, por lo tanto, se ejecutan en la parte superior inferior de la moda.

Nota: Las funciones pueden anularse no las variables.

Dado que está heredando propiedades de clase base en clase derivada, puede haber algunas situaciones en las que el constructor de clase derivado requiera algunas de las variables de clase base para inicializar sus variables. Entonces primero tiene que inicializar las variables de la clase base, y luego las variables derivadas de la clase. Es por eso que Java llama al constructor de primera clase y luego al constructor de clase derivado.

Y tampoco tiene sentido inicializar la clase para niños sin inicializar la clase para padres.

El constructor de Superclase se invoca primero porque todos los métodos en el progtwig se presentan primero en el montón y después de la comstackción se almacenan en la stack, debido a lo cual se llama primero al constructor de la clase superior.

En palabras simples, si la superclase tiene un constructor parametrizado, debe llamar explícitamente a super (params) en la primera línea de su constructor de la clase secundaria. De forma implícita, todos los constructores de la superclase se llaman hasta que la clase de objeto sea reachead.

Hay una llamada a super () predeterminada en sus constructores de subclases predeterminados.

  //Default constructor of subClass subClass() { super(); } 

“Si un constructor no invoca explícitamente un constructor de superclase, el comstackdor de Java inserta automáticamente una llamada al constructor sin argumento de la superclase. Si la superclase no tiene un constructor sin argumento, obtendrá un error en tiempo de comstackción . Object tiene un constructor así, por lo que si Object es la única superclase, no hay problema “.
(fuente: https://docs.oracle.com/javase/tutorial/java/IandI/super.html )

Trataré de responder esto desde una perspectiva diferente.

Supongamos que Java no llama automáticamente al superconstructor. Si heredas la clase, tendrías que llamar implícitamente al superconstructor o reescribirlo tú mismo. Esto requeriría que tengas un conocimiento interno de cómo funciona la superclase, lo cual es malo. También sería necesario reescribir el código, que tampoco es bueno.

Estoy de acuerdo en que llamar al superconstructor detrás de escena es un poco poco intuitivo. Por otro lado, no estoy seguro de cómo podrían haberlo hecho de una manera más intuitiva.

Como sabemos, las variables miembro (campos) de una clase deben inicializarse antes de crear un objeto porque estos campos representan el estado del objeto. Si estos campos no se inician explícitamente, el comstackdor les proporciona implícitamente valores predeterminados llamando al constructor predeterminado sin argumento. Es por eso que el constructor de subclases invoca el constructor predeterminado de superclase sin argumento o el comstackdor invoca implícitamente. Las variables locales no se proporcionan por valor predeterminado por el comstackdor.

aquí su prueba de ampliación a su clase de prueba1 lo que significa que puede acceder a todos los métodos y variables de prueba en su prueba1. Tenga en cuenta que puede acceder a los métodos o variables de clase solo si se le asigna memoria y para eso necesita algún constructor ya sea por defecto o parametrizado, así que aquí cuando el comstackdor encuentre que está extendiendo una clase, intentará encontrar el constructor de clase superior para que pueda acceder a todos sus métodos.

Padres sale primero !! Y al igual que el mundo real, el niño no puede existir sin los padres. Por lo tanto, los padres que inician (SuperClass) primero es importante para poder utilizar el progtwig en las clases de niños (subclase).