JavaRush /Blog Java /Random-ES /Constructores de clase base

Constructores de clase base

Publicado en el grupo Random-ES
¡Hola! La última vez hablamos de constructores y aprendimos mucho sobre ellos. Ahora hablaremos de los constructores de clases base. ¿ Qué es una clase base ? El hecho es que en Java varias clases diferentes pueden tener un origen común. Constructores de clase base - 2Esto se llama herencia . Varias clases de descendientes pueden tener una clase de ancestro común. Por ejemplo, imaginemos que tenemos una clase Animal(animal):
public class Animal {

   String name;
   int age;
}
Podemos crear para ello, por ejemplo, 2 clases descendientes: Caty Dog. Esto se hace usando la palabra clave extends.
public class Cat extends Animal {

}

public class Dog extends Animal {

}
Esto puede resultarnos útil en el futuro. Por ejemplo, si la tarea es cazar ratones, crearemos un objeto en el programa Cat. Si la tarea es correr detrás de un palo, entonces usamos el objeto Dog. Y si creamos un programa que simule una clínica veterinaria, funcionará con la clase Animal(para poder tratar tanto a perros como a gatos). Es muy importante recordar para el futuro que al crear un objeto, primero se llama al constructor de su clase base , y solo entonces se llama al constructor de la clase en sí, cuyo objeto estamos creando. Es decir, al crear un objeto, Catprimero funcionará el constructor de la clase Animal, y solo después el constructor Cat. Para asegurarnos de esto, agreguemos a los constructores Caty Animalenviemos a la consola.
public class Animal {

   public Animal() {
       System.out.println("Constructor de animales completado");
   }
}


public class Cat extends Animal {

   public Cat() {
       System.out.println("¡El constructor Cat funcionó!");
   }

   public static void main(String[] args) {
       Cat cat = new Cat();
   }
}
Salida de consola:

Отработал конструктор Animal
Отработал конструктор Cat!
De hecho, ¡así es como funciona todo! ¿Para qué sirve? Por ejemplo, para evitar duplicar campos comunes de dos clases. Por ejemplo, todo animal tiene corazón y cerebro, pero no todos los animales tienen cola. Podemos declarar campos comunes a todos los animales brainen heartla clase principal Animaly un campo tailen la subclase Cat. Ahora crearemos un constructor para la clase Cat, donde pasaremos los 3 campos.
public class Cat extends Animal {

   String tail;

   public Cat(String brain, String heart, String tail) {
       this.brain = brain;
       this.heart = heart;
       this.tail = tail;
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Cerebro", "Corazón", "Cola");
   }
}
Prestar atención:El constructor funciona correctamente, aunque la clase Catno tiene campos brainy heart. Estos campos fueron "extraídos" de la clase base Animal. La clase descendiente tiene acceso a los campos de la clase base, por lo que Catson visibles en nuestra clase. Por lo tanto, no necesitamos Catduplicar estos campos en la clase; podemos tomarlos de la clase Animal. Además, podemos llamar explícitamente al constructor de la clase base en el constructor de la clase descendiente. La clase base también se llama " superclase ", razón por la cual Java usa la palabra clave super. En el ejemplo anterior
public Cat(String brain, String heart, String tail) {
       this.brain = brain;
       this.heart = heart;
       this.tail = tail;
   }
Asignamos por separado cada campo que está en nuestra clase principal. De hecho, no es necesario que haga esto. Basta con llamar al constructor de la clase padre y pasarle los parámetros necesarios:
public class Animal {

   String brain;
   String heart;

   public Animal(String brain, String heart) {
       this.brain = brain;
       this.heart = heart;
   }

public class Cat extends Animal {

   String tail;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       this.tail = tail;
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Cerebro", "Corazón", "Cola");
   }
}
En el constructor, Catllamamos al constructor Animaly le pasamos dos campos. Sólo tenemos que inicializar explícitamente un campo, tailque Animalno está presente. ¿Recuerda que dijimos que cuando se crea un objeto, primero se llama al constructor de la clase principal? ¡Es por eso que la palabra super()siempre debe aparecer primero en el constructor! De lo contrario, la lógica de los constructores se romperá y el programa generará un error.
public class Cat extends Animal {

   String tail;

   public Cat(String brain, String heart, String tail) {
       this.tail = tail;
       super(brain, heart);//¡error!
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Cerebro", "Corazón", "Cola");
   }
}
El compilador sabe que al crear un objeto de una clase descendiente, se llama primero al constructor de la clase base. Y si intenta cambiar manualmente este comportamiento, no lo permitirá.

El proceso de creación de un objeto.

Arriba vimos un ejemplo con una clase base y principal: Animaly Cat. Ahora, usando estas dos clases como ejemplo, veremos el proceso de creación de un objeto e inicialización de variables. Sabemos que las variables son estáticas y variables de instancia (no estáticas). También sabemos que la clase base Animaltiene sus propias variables y la clase descendiente Cattiene las suyas propias. Agreguemos una variable estática a la clase para Animalmayor claridad . CatLa variable animalCountde clase Animalsería el número total de especies animales en la Tierra y la variable catsCountsería el número de especies de gatos. Además, asignaremos valores iniciales a todas las variables no estáticas de ambas clases (que luego cambiarán en el constructor).
public class Animal {

   String brain = "El valor inicial del cerebro en la clase Animal";
   String heart = "El valor inicial de corazón en la clase Animal";

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println("Se está ejecutando el constructor de la clase base Animal");
       System.out.println("¿Ya se inicializaron las variables de la clase Animal?");
       System.out.println("El valor actual de la variable estática animalCount = " + animalCount);
       System.out.println("Valor actual del cerebro en la clase Animal =" + this.brain);
       System.out.println("Valor actual del corazón en la clase Animal =" + this.heart);
       System.out.println("¿Ya se inicializaron las variables de la clase Cat?");
       System.out.println("El valor actual de la variable estática catsCount = " + Cat.catsCount);

       this.brain = brain;
       this.heart = heart;
       System.out.println("¡Constructor de clase base animal completado!");
       System.out.println("Valor actual del cerebro =" + this.brain);
       System.out.println("Valor actual del corazón = " + this.heart);
   }
}

public class Cat extends Animal {

   String tail = "El valor inicial de la cola en la clase Cat";

   static int catsCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println("Se ha iniciado el constructor de la clase Gato (ya se ha ejecutado el constructor Animal)");
       System.out.println("El valor actual de la variable estática catsCount = " + catsCount);
       System.out.println("Valor actual cola =" + this.tail);
       this.tail = tail;
       System.out.println("Valor actual cola =" + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Cerebro", "Corazón", "Cola");
   }
}
Entonces, creamos un nuevo objeto de la clase Catheredada de Animal. Agreguemos una salida de consola detallada a nuestro programa para ver qué sucederá y en qué orden. Esto es lo que se mostrará en la consola como resultado de la creación de un objeto Cat:

Выполняется конструктор базового класса Animal
Были ли уже проинициализированы переменные класса Animal?
Текущее significado статической переменной animalCount = 7700000
Текущее significado brain в классе Animal = Изначальное significado brain в классе Animal
Текущее significado heart в классе Animal = Изначальное significado heart в классе Animal
Были ли уже проинициализированы переменные класса Cat?
Текущее significado статической переменной catsCount = 37
Конструктор базового класса Animal завершил работу!
Текущее significado brain = Мозг
Текущее significado heart = Сердце
Конструктор класса Cat начал работу (конструктор Animal уже был выполнен)
Текущее significado статической переменной catsCount = 37
Текущее significado tail = Изначальное significado tail в классе Cat
Текущее significado tail = Хвост
Entonces, ahora podemos ver claramente en qué orden se inicializan las variables y se llaman los constructores al crear un nuevo objeto:
  1. Se inicializan las variables estáticas de la clase base ( ) Animal. En nuestro caso, a la variable animalCountde clase Animalse le asigna el valor 7700000.

  2. Se inicializan las variables estáticas de la clase descendiente ( ) Cat. Preste atención: todavía estamos dentro del constructor Animaly la consola ya dice:

    
        Выполняется конструктор базового класса Animal
        Были ли уже проинициализированы переменные класса Animal?
        Текущее significado статической переменной animalCount = 7700000
        Текущее significado brain в классе Animal = Изначальное significado brain в классе Animal
        Текущее significado heart в классе Animal = Изначальное significado heart в классе Animal
        Были ли уже проинициализированы переменные класса Cat?
        Текущее significado статической переменной catsCount = 37
  3. A continuación, se inicializan las variables no estáticas de la clase base . Les asignamos específicamente valores iniciales, que luego se cambian por otros nuevos en el constructor. El constructor Animalaún no ha completado su trabajo, pero ya se brainhan heartasignado los valores iniciales:

    
        Выполняется конструктор базового класса Animal
        Были ли уже проинициализированы переменные класса Animal?
        Текущее significado статической переменной animalCount = 7700000
        Текущее significado brain в классе Animal = Изначальное significado brain в классе Animal
        Текущее significado heart в классе Animal = Изначальное significado heart в классе Animal
  4. El constructor de la clase base comienza a funcionar .

    Ya hemos visto que esta etapa es solo la cuarta consecutiva: en los primeros tres puntos, en el momento en que el constructor comienza a trabajar, Animalya se han asignado valores a muchas variables.

  5. Inicializando campos no estáticos de una clase secundaria ( Cat).

    Sucede antes de que el diseñador Catcomience a trabajar.

    En el momento en que empezó a trabajar, la variable tailya tenía un valor:

    
    Конструктор класса Cat начал работу (конструктор Animal уже был выполнен)
    Текущее significado статической переменной catsCount = 37
    Текущее significado tail = Изначальное significado tail в классе Cat
  6. El constructor de la clase descendiente se llama Cat

¡Así es como se ve el proceso de creación de un objeto en Java! Debo decir que no somos grandes fanáticos del cramming, pero es mejor memorizar el orden de inicialización de variables y llamar a constructores y recordarlos para el futuro . Esto aumentará enormemente su comprensión del progreso del programa y el estado de sus objetos en un momento dado. Además, las clases a menudo no tienen clases principales directas (superclases/clases base). En este caso, los elementos asociados a la clase base no se ejecutarán.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION