Ir al contenido
wannacode

Constructores y this

En resumen: Un constructor es un método especial con el nombre de la clase que se ejecuta con new y rellena los campos del objeto nuevo, y this es el propio objeto.

Problema

Un café de 0 €

Creas un producto, igual que en la lección anterior, y rellenas los campos línea por línea. Se te olvidó una línea:

Product coffee = new Product();
coffee.name = "Café";
coffee.quantity = 2;
System.out.println(coffee.name + ": " + coffee.price * coffee.quantity + " €");
Salida
Café: 0.0 €

El café cuesta 0 €. El compilador no se queja: para él, el precio tiene un valor, 0. Cuantos más campos tiene una clase, más fácil es saltarse uno. Y un producto sin precio ni siquiera debería poder existir.

La idea

Constructor: sin estos datos no hay objeto

Una clase puede decir qué necesita antes de que puedas crear un objeto a partir de ella. Para eso sirve el constructor: un método especial que se ejecuta con new.

Main.java
class Product {
public String name;
public double price;
public int quantity;
public Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
}
public class Main {
public static void main(String[] args) {
Product coffee = new Product("Café", 7.50, 2);
System.out.println(coffee.name + ": " + coffee.price * coffee.quantity + " €");
}
}
Salida
Café: 15.0 €
  • El constructor tiene exactamente el mismo nombre que la clase: Product.
  • No tiene tipo de retorno, ni siquiera void.
  • Sus parámetros son los datos sin los que un producto no puede existir. Los pasas en los paréntesis de new: new Product("Café", 7.50, 2).

Ahora no hay forma de olvidar el precio. Si pasas dos argumentos en lugar de tres, el programa no compila.

public Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
Product coffee = new Product("Café", 7.50, 2);
System.out.println(coffee.name + ": " + coffee.price * coffee.quantity + " €");
Paso a paso, en palabras
  1. new reserva un objeto nuevo. Sus campos tienen valores por defecto.
  2. Se ejecuta el constructor. Los argumentos se copian en sus parámetros.
  3. this.name = name: del parámetro al campo de este objeto.
  4. Lo mismo para el precio y la cantidad.
  5. El constructor termina y los parámetros desaparecen. coffee recibe una flecha al objeto terminado.
  6. El objeto sale de new ya rellenado, así que el precio no es 0.

La idea

this: el campo de este objeto

Dentro del constructor hay dos cosas que se llaman name: el parámetro y el campo. El nombre solo es el parámetro, porque está «más cerca». Para el campo escribes this.name.

public Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}

this es el objeto que se está creando ahora mismo. this.name = name; significa «guarda el parámetro name en el campo name de este objeto».

Los parámetros podrían tener otros nombres (productName), y entonces no necesitarías this. Pero en Java los nombres iguales son habituales, porque se ve enseguida qué parámetro va a qué campo.

Pruébalo

Encuentra el error

El programa debería imprimir «Té: 3.2 €». El precio aparece, pero el nombre no. ¿Qué línea tiene el error?

Elige la línea con el error.

La idea

¿Y el new Product() de la lección anterior?

En la lección anterior no había constructor, y new Product() funcionaba. Si no escribes un constructor, el compilador añade uno vacío, sin parámetros. Se llama constructor por defecto, y deja los campos con sus valores por defecto.

En cuanto escribes tu propio constructor, el vacío desaparece:

Product empty = new Product();
Error de compilación
error: constructor Product in class Product cannot be applied to given types;

De eso se trata: ya no se puede crear un producto sin nombre ni precio. Si aun así necesitas un constructor vacío, escríbelo tú.

La idea

Varios constructores

La mayoría de los productos del carrito van de uno en uno. Escribir 1 cada vez cansa.

Puedes darle a la clase un segundo constructor, sin la cantidad. Va junto al primero:

public Product(String name, double price) {
this.name = name;
this.price = price;
this.quantity = 1;
}

Es la sobrecarga del módulo «Métodos»: un nombre, parámetros distintos. Con new, el compilador elige el constructor según los argumentos.

Más precisamente, para curiosos

Los dos constructores repiten las mismas líneas. En lugar de eso, el más corto puede llamar al más largo:

public Product(String name, double price) {
this(name, price, 1);
}

this(...) llama a otro constructor de la misma clase. Tiene que ser la primera línea del constructor.

Así, si mañana añades una comprobación del precio, la escribes en un solo constructor.

Pruébalo

¿Qué constructor?

¿Qué imprimirá el programa?

class Product {
public String name;
public double price;
public int quantity;
public Product(String name, double price) {
this.name = name;
this.price = price;
this.quantity = 1;
}
public Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
}
Product bread = new Product("Pan", 1.20);
Product milk = new Product("Leche", 2.10, 3);
System.out.println(bread.quantity + " " + milk.quantity);
Respuesta

Pruébalo

¿Cómo se llama el constructor?

¿Qué va en el hueco?

class Book {
    public String title;
    public String author;

    public (String title, String author) {
        this.title = title;
        this.author = author;
    }
}

Ejercicio

Objetos creados completos

Resuélvelos en tu editor. Cada clase recibe un constructor con parámetros para todos sus campos.

1. Persona. Una clase Person con un nombre y una edad. Crea dos personas e imprime sus datos.

Salida
María, 34 años
Pablo, 19 años

2. Animal. Una clase Animal con una especie y una edad. Crea un gato de 3 años y un perro de 7.

Salida
Especie: gato, edad: 3
Especie: perro, edad: 7

3. Paso de baile. Una clase DanceMove con un nombre y una duración en segundos. En la lección «Métodos de instancia», el paso aprenderá a «ejecutarse» solo.

Salida
moonwalk: 5 s

Más práctica

  • Un libro con constructor. Reescribe Book de la lección anterior con un constructor Book(title, author). ¿Cuántas líneas ahorraste en main?
  • Un producto con dos constructores. Product con dos constructores, como en la lección. Haz un array { new Product("Pan", 1.20, 2), new Product("Café", 7.50) } e imprime el nombre y la cantidad de cada uno: «Pan x2», «Café x1». Después haz que el constructor más corto llame al más largo.
  • Reserva. Una clase Booking con el nombre del huésped, el número de noches y el precio por noche. Imprime cuánto cuesta la estancia: 3 noches a 85 € son 255 €.

Test

Ponte a prueba

1. ¿Cuándo se ejecuta el constructor?
2. ¿Qué tipo de retorno va delante del nombre del constructor?
3. La clase solo tiene un constructor Product(name, price). ¿Qué pasa con new Product()?
4. El constructor dice this.name = name; ¿Qué es this.name?
5. La clase tiene dos constructores: uno con nombre y precio, y otro con nombre, precio y cantidad. ¿Cómo se llama esto?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·