"¡Hola, Amigo! Ahora te voy a contar cómo se crean los objetos".

"¿Qué tiene de complicado, tío Rishi? ¡Escribes nuevo y el nombre de la clase, indicas el constructor correcto y listo!"

"Eso es cierto. Pero, ¿qué sucede dentro del objeto cuando haces eso?"

"¿Lo que sucede?"

"Esto es lo que sucede: el objeto se crea en varias etapas".

1)  Primero, se asigna memoria para todas las variables miembro de la clase.

2)  Luego se inicializa la clase base.

3)  Luego se asignan valores a todas las variables, si se especifica alguna.

4)  Finalmente, se llama al constructor.

"No parece muy difícil: primero las variables, luego el constructor".

"Veamos cómo funciona esto en un ejemplo con dos clases:"

Código Descripción
class Pet
{
 int x = 5, y = 5; ←-
 int weight = 10; ←-

 Pet(int x, int y)
 {
  this.x = x; ←-
  this.y = y; ←-
 }
}
class Cat extends Pet
{
 int tailLength = 8; ←-
 int age;
 Cat(int x, int y, int age)
 {
  super(x, y); ←-
  this.age = age; ←-
 }
}
Declare dos clases: Mascota (mascota) y Gato (gato).

En la clase Cat, vemos una llamada explícita al constructor de la clase base .
Siempre debe estar en la primera línea del constructor.

Esto es lo que sucede después de que se asigna la memoria:
18  : llame al constructor de la clase base.
3, 4  – inicializar variables en Pet.
8, 9  : ejecuta el código en el constructor Pet.

Entonces la clase Cat comienza a inicializarse.
14  – inicializar variables en Cat
19  – ejecutar el código en el constructor Cat

public static void main(String[] args)
{
 Cat cat = new Cat (50, 50, 5);
}

"Eso es un poco confuso. ¿Por qué es tan complicado?"

"En realidad, no es difícil si sabes lo que realmente está pasando:"

Si una clase no tiene constructores, se creará uno automáticamente.

Constructor predeterminado
class Cat
{
 int x = 5;
 int y = 5;
}
class Cat
{
 int x = 5;
 int y = 5;
 public Cat() 
 {
 }
}

Si no llama al constructor de la clase base, se llamará automáticamente.

Llamada del constructor de la clase base.
class Pet
{
 public String name;
}
class Pet extends Object
{
 public String name;
 public Pet()
 {
  super();
 }
}
class Cat extends Pet
{
 int x = 5;
 int y = 5;
}
class Cat extends Pet
{
 int x = 5;
 int y = 5;
 public Cat()
 {
  super();
 }
}

Las variables miembro se inicializan en el constructor.

Inicialización de variables miembro
class Cat
{
 int x = 5;
 int y = 5;
}
class Cat
{
 int x;
 int y;
 public Cat()
 {
  super();
  this.x = 5;
  this.y = 5;
  }
}
lo que realmente sucede
class Pet
{
 int x = 5, y = 5;
 int weight = 10;
 Pet(int x, int y)
 {
  this.x = x;
  this.y = y;
 }
}

class Cat extends Pet
{
 int tailLength = 8;
 int age;
 Cat(int x, int y, int age)
 {
  super(x, y);
  this.age = age;
 }
}
class Pet extends Object
{
 int x;
 int y;
 int weight;

 Pet(int x, int y)
 {
  //call of the base class's constructor
  super();
  //initialize variables
  this.x = 5;
  this.y = 5;
  this.weight = 10;
  //execute the constructor code
  this.x = x;
  this.y = y;
 }
}
class Cat extends Pet
{
 int tailLength;
 int age;
 Cat(int x, int y, int age)
 {
  //call of the base class's constructor
   super(x, y);
  //initialize variables
  this.tailLength = 8;
  //execute the constructor code
  this.age = age;
 }
}

"Ahora está mucho más claro: primero la clase base, luego las variables fuera del constructor, luego el código del constructor".

"¡Bien hecho, Amigo! ¡Eso es todo!"