jueves, 5 de marzo de 2026

■ ¿Por qué encapsular?

Para entender el encapsulamiento debe entenderse primero cómo funciona la Programación Orientada a Objetos (POO).

Cuando hablamos de Objetos en programación, debemos pensar en clases y propiedades, una clase es la representación del objeto del mundo real, por ejemplo, si queremos manejar empleados crearíamos una clase llamada "Empleado", y así como el empleado tiene características que lo identifican, la clase tiene propiedades, que serían las características del empleado, por ejemplo, el empleado tiene nombre, teléfono, correo, pertenece a un departamento y tiene un sueldo, todos estos datos los podemos representar como propiedades de la clase, a esto se le llama abstracción.

Luego de hacer la abstracción, la clase empleado podría quedar así:

class Empleado {
    String nombre;
    Strign telefono;
    String correo;
    double sueldo;
}


Para acceder a dichas propiedades desde la clase principal, basta con instanciar la clase Empleado, al crear un objeto de la misma dicho objeto automáticamente ya tiene las propiedades de la clase, por ejemplo:

public class Control {
    public static void main(String[] args) {
        Empleado emp = new Empleado(); // Instancia de Empleado

        //emp es el objeto Empleado
        //y puede disponer de sus propiedades así
        emp.nombre = "John Smith";
        emp.telefono = "123456789";
        emp.correo = "jsmith@domain.com";
        emp.sueldo = 10000.00;
    }
}


Hasta aquí todo parece correcto, creé un objeto Empleado y luego lo inicialicé accediendo directamente a sus propiedades, eso funciona perfectamente, si luego de asignar los datos del empleado los mostrara en pantalla así:

    System.out.println("Nombre: " + emp.nombre);
    System.out.println("Teléfono: " + emp.telefono);
    System.out.println("Correo: " + emp.correo);
    System.out.println("Sueldo: " + emp.sueldo);



Esto funcionaría perfectamente, pero hay un detalle: el acceso.

Como puede observarse en el ejemplo, bastó con crear el objeto "emp" de tipo "Empleado" (acción de instanciar), para que mediante este objeto se pudiera acceder a las propiedades de la clase, darle un nombre, un teléfono, un correo y un sueldo.

Hasta este punto podrían pensar "obvio, ese es el objetivo", pero aquí es donde entra un tema muy importante el POO, el Encapsulamiento.

Encapsular es ocultar los atributos y métodos de la clase para restringir o controlar su acceso desde el exterior. ¿Por qué se hace esto?, se hace para evitar que se pueda acceder a información, que queremos mantener como privada, desde otras clases y que dichas clases solo puedan acceder a lo que nosotros permitamos o de la forma en la que se los permitamos.

Por ejemplo en la clase Empleado, ¿qué evitaría que el usuario en la clase principal (main) pusiera texto en el teléfono, o un correo mal estructurado o un sueldo negativo?, algo así:

Empleado emp = new Empleado();

// Inicializamos valores
emp.nombre = "John";
emp.telefono = "no tiene";
emp.correo = "jsmit@";
emp.sueldo = -5000;


Dado que las propiedades de Empleado son públicas, hacer lo anterior no representa un error sintáctico, es decir, es válido, se permite, pero mirándolo desde la lógica está mal, aquí es donde se aplica el encapsulamiento.


■ Encapsulamiento

Encapsular es volver privadas las propiedades de Empleado para que estas solo puedan ser accedidas dentro de la propia clase Empleado y no desde afuera. ¿Cómo hacemos esto?, simplemente les anteponemos "private":

class Empleado {
    private String nombre;
    private Strign telefono;
    private String correo;
    private double sueldo;
}

Cuando las propiedades no tienen la palabra reservada "private" se toman como públicas, para indicar que son públicas se les antepone "public", no es un error no ponérselo pero como buena práctica se sugiere colocar el "public" para cuando queramos que sean públicas.

Si colocamos las propiedades como "
private", forzamos a que el acceso a ellas solo se pueda hacer mediante los propios métodos de la clase, pero estos también deberán ser públicos, por lo que podemos tener tanto métodos públicos como privados.

A estos métodos para inicializar las variables se le llama "setters", serían de la siguiente forma:

public void setNombre(String _nombre) {
    this.nombre = _nombre;
}

public void setTelefono(String _telefono) {
    this.telefono = _telefono;
}

public void setCorreo(String _correo) {
    this.correo = _correo;
}

public void setSueldo(double _sueldo) {
    this.sueldo = _sueldo;
}


Donde:

  • "this" se refiere a que la variable es de la propia clase, no es forzoso que lleve el "this" pero se sugiere ponerlo.
  • Las variables pasadas por parámetro son los valores que se asignarán a las propiedades del objeto, mismos que pasamos al momento de llamar a los métodos.

Hasta este punto se encapsularon las propiedades pero no se ha solucionado el problema planteado anteriormente, ya que los métodos públicos que acceden a las propiedades, reciben valores y los asignan directamente a las variables. Es aquí donde hay que ponerse creativos.

Si creamos métodos públicos para inicializar las variables, entonces ¿podemos hacer más cosas dentro de los métodos?, es decir, meter más instrucciones, la respuesta es si, lo que significa que podemos analizar los valores recibidos y determinar si los asignamos o no a las  variables.

Por ejemplo:

Evitar que intenten guardar un texto como teléfono:

public void setTelefono(String _telefono) {
    if (_telefono.matches("\\d+")) {
        // Si _teléfono es numérico, lo asignamos
        this.telefono = _telefono;
    } else {
        // Si _teléfono no es numérico ponemos solo un guion
        this.telefono = "-";
    }
}


Verificar que el correo ingresado tenga estructura de correo:

public void setCorreo(String _correo) {
    if (_correo.matches(".+\\@.+")) {
        // Si _correo tiene texto + @ + texto, lo asignamos
        this.correo = _correo;
    } else {
        // Si no, solo asignamos un guión
        this.correo = "-";
    }
}


Evitar que el usuario ponga un sueldo negativo:

public void setSueldo(double _sueldo) {
    if (_sueldo > 0) {
        // Si sueldo es mayor que 0, se asigna
        this.sueldo = _sueldo;
    } else {
        // Si no, solo se pone 0.0
        this.sueldo = 0.0;
    }
}



Esto solo es un ejemplo de cómo funciona la encapsulación y el acceso por métodos públicos, la solución dependerá de la problemática y del cómo quiera manejarse.

No hay comentarios:

Publicar un comentario