Saltar al contenido principal

Constructores, Getters y Setters, toString

¿Qué es el Encapsulamiento?

Es uno de los pilares fundamentales de la POO y consiste en proteger los datos internos de una clase, haciendo que solo puedan ser accedidos o modificados a través de métodos controlados: los getters y setters.

Esto permite:

  • Validar datos antes de asignarlos.
  • Evitar accesos no deseados.
  • Mantener el principio de ocultamiento de la información.

¿Qué es un Constructor?

Un constructor es un método especial que se ejecuta automáticamente al crear un objeto.

Un constructor es un método especial que se llama automáticamente cuando se crea un objeto de una clase. Su objetivo es inicializar el estado (atributos) del objeto.

Diferencias clave con un método normal

CaracterísticaConstructorMétodo normal
Tiene nombre de la claseNo necesariamente
Tiene tipo de retornoNoSí (puede ser void o cualquier tipo)
Se invoca automáticamenteAl usar newManualmente

Tipos de constructores

Existen 3 tipos:

  1. Constructor implícito: Si no defines ningún constructor, Java crea uno automáticamente sin parámetros.

    public class Book {
    private String title;
    // Java genera automáticamente: public Book() {}
    }
  2. Constructor vacío: Tú mismo defines un constructor sin parámetros. Se usa cuando quieres permitir la creación del objeto sin establecer valores de inmediato.

    public class Book  {
    // puedes dejarlo vacío o incluir un mensaje
    public Book() {}
    }
  3. Constructor con parámetros: Permite inicializar el objeto directamente con datos personalizados, evitando llamadas repetidas a setters.

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

Sobrecarga de constructores

Puedes definir varios constructores con diferente número o tipo de parámetros. Esto se llama overloading.

public class Book {
private String title;
private String author;

public Book() {
this.title = "Unknown";
this.author = "Anonymous";
}

public Book(String title) {
this.title = title;
this.author = "Anonymous";
}

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

Así puedes crear libros de diferentes formas:

Book a = new Book(); // Sin datos
Book b = new Book("1984"); // Solo título
Book c = new Book("1984", "Orwell"); // Título y autor

Analogías

  1. Constructor como la receta inicial: El constructor es la receta básica para preparar un objeto. Si no dices nada (constructor vacío), te entrega la versión por defecto. Si das parámetros, creas una versión personalizada.

  2. Constructor como el formulario de inscripción: Cuando un estudiante se matricula en la universidad (se construye un objeto Student), debe llenar un formulario con su nombre, ID, y programa académico. Ese formulario es el constructor: establece sus datos desde el principio.

Buenas prácticas con constructores

RecomendaciónExplicación
Usa thisPara distinguir entre atributos y parámetros con el mismo nombre
Aplica sobrecargaDa flexibilidad a quienes usan la clase
Valida datosPuedes validar valores en el constructor (ej. gpa >= 0)
Mantén la clase coherenteUn constructor debe dejar el objeto en un estado válido

¿Qué son Getters y Setters?

Son métodos públicos que permiten leer (get) y modificar (set) los atributos privados.

  • getName() → devuelve el valor del nombre.
  • setName("David") → asigna un nuevo valor.

Esto permite aplicar el principio "acceso controlado", útil para validaciones.

En Java, los getters y setters son métodos públicos que permiten acceder y modificar los atributos privados de una clase, siguiendo el principio de encapsulamiento.

¿Por qué usar getters y setters?

MotivoBeneficio
Encapsular el estadoControla el acceso directo a los atributos
Validar antes de asignarPermite comprobar o transformar datos antes de guardarlos
Ocultar implementaciónPuedes cambiar cómo funciona internamente sin afectar al exterior
Reforzar mantenibilidadFacilita el mantenimiento y crecimiento del sistema

Estructura general

La convención en Java es que los métodos getX() y setX() usen el mismo nombre del atributo, con la primera letra en mayúscula.

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

Buenas Prácticas con Getters y Setters

PrácticaExplicación
Validar datos en setX()Evita estados incorrectos del objeto
No uses getX() innecesariosSolo para atributos relevantes al exterior
getX() nunca modificaNunca debe alterar el estado, solo devolver información
Usa boolean isActive()Para atributos booleanos, usar isX() en vez de getX()
Anótalos con @Override si correspondeSi estás sobrescribiendo un método existente

¿Qué es el método toString()?

Es un método especial heredado de la clase Object que sirve para devolver una representación en texto de un objeto. Por defecto, devuelve algo como:

Student@3e25a5

Esto es poco útil. Por eso, es una práctica común sobrescribirlo (@Override) para mostrar información legible y significativa del objeto.

@Override // Se usa el decorador para sobrescribir el método
public String toString() {
return name + " (" + id + ")";
}

¿Por qué es importante sobrescribir toString()?

BeneficioDescripción
Facilita depuraciónVer claramente los valores internos al imprimir el objeto
Mejora trazabilidadPermite entender qué contiene una colección de objetos (como ArrayList)
Útil para logs o exportaciónProporciona salida legible para archivos, reportes o visualización en GUI

Buenas Prácticas con toString()

PrácticaExplicación
Sobrescribir siemprePara evitar la salida genérica de Object
Mostrar solo lo necesarioEvita imprimir datos sensibles (contraseñas, tokens…)
Usar @OverridePara dejar claro que estás reemplazando el método heredado
Úsalo en métodos System.out.println()...y en logs o visualizaciones automáticas de objetos
Usa un formato uniformePara facilitar la lectura e integración con otras herramientas

Código en Java

Mini Proyecto

Descripción

Desarrolla un pequeño sistema en consola que permita:

  • Crear objetos de tipo Product.
  • Usar un constructor con parámetros.
  • Utilizar getters y setters para acceder y modificar sus atributos.
  • Imprimir la información de los productos usando toString().
  • Almacenar varios productos en un ArrayList.

Requisitos funcionales

  1. Crear una clase Product con los siguientes atributos:
    • String name
    • String code
    • double price
    • int quantity
  2. Implementar:
    • Un constructor vacío y uno con todos los parámetros.
    • Getters y Setters para cada atributo.
    • Método sobrescrito toString() para mostrar la información del producto.
  3. En el método main:
    • Crear al menos 5 productos y almacenarlos en una lista.
    • Modificar al menos un producto con setters.
    • Imprimir la información de todos los productos con un bucle usando toString().

Reflexión final

Principios SOLID aplicados a los constructores:

  • S (Single Responsibility): Cada constructor tiene una única función: inicializar el objeto correctamente.
  • O (Open/Closed): Puedes agregar nuevos constructores sin modificar los anteriores.
  • L (Liskov Substitution): En clases hijas, puedes invocar super() para llamar al constructor de la superclase.

Principios SOLID aplicados a los getters y setters:

  • S (Single Responsibility): Acceso y modificación controlada del estado del objeto
  • O (Open/Closed): Se pueden agregar nuevas validaciones sin afectar usuarios externos
  • L (Liskov Substitution): Clases hijas pueden sobrescribir getters/setters sin romper compatibilidad

Principios SOLID aplicados al toString():

  • S (Single Responsibility): toString() solo debe mostrar el estado del objeto como texto
  • O (Open/Closed): Puedes extender la clase y redefinir toString() según el nuevo contexto
  • L (Liskov Substitution): Cualquier subclase puede usar su propia versión de toString()

Recursos y Bibliografía