POO II – Encapsulamiento

A menudo, las aplicaciones que originalmente creamos tienden a crecer, o a “escalar” como se dice en el argot desarrollador, y si no hemos diseñado bien nuestra aplicación, al crecer y aumentar el número de clases y demás, es muy probable que hayan conflictos. Afortunadamente contamos con un legado de buenas prácticas y principios de desarrollo de software, uno de estos es, el encapsulamiento.

El encapsulamiento no es más que proteger los atributos de una clase del exterior, haciéndolas invisibles para el resto de clases, de esta manera, evitamos que otra clase acceda directamente a los atributos y pueda comprometerlas.

Traigamos un ejemplo real, supongamos que tenemos dos clases, Perro y Gato:

public class Dog {

    String name;

}

public class Cat {

    String name;

}

Y una tercera donde haremos una pequeña prueba. Supongamos que nos encargan asignarle un nombre al perro pero no al gato, pero nos equivocamos de objeto y en su lugar le asignamos un nombre al gato:

public class Main {

    public static void main(String[] args) {

        Dog dog = new Dog();
        Cat cat = new Cat();
        cat.name = "Firulais";

    }

}

¿Qué nos detiene de hacer algo así? Pues la respuesta es que no nos detiene nada, se puede cambiar sin escrúpulos los atributos de Cat porque son públicas y todo el mundo las puede manosear. Para evitar esto debemos de aplicar el modificador private a los atributos de Dog y Cat:

public class Dog { // lo mismo para Cat

    private String name;

}

Ahora si intentamos hacer lo que hicimos antes en el método main veremos que no nos dejará siquiera compilar. Esto es porque ahora el atributo name de Dog y Cat son invisibles para cualquier otro contexto que no sea la misma clase en la que se le declaran.

Un atributo o método marcado como private, solo será visible por la misma clase en donde se le declara.

Ahora, viene otra pregunta, ¿cómo accedemos al atributo name? Esto lo veremos a continuación.

Constructores y getters/setters

Veamos la definición de constructor:

Los constructores son métodos especiales, no tienen tipo de retorno y deben llamarse igual que la clase. Un constructor es un medio por el cual construir una instancia de esa clase, por eso el nombre constructor. La razón por la que podíamos crear objetos tipo Dog y Cat es porque toda clase en Java tiene un constructor sin parámetros por defecto, lo cual heredan todas las clases de la clase Object.

Como vemos, un constructor es un método también pero con algunas restricciones. Entonces, como método puede recibir parámetros:

Dog(String name) { // lo mismo para Cat

    this.name = name;

}

NOTA: La palabra this hace referencia a ‘esto’, es decir, al contexto en donde se encuentra. Por ende, dentro de Dog, this es igual a Dog, por esta razón podemos acceder a name mediante this.

Esto se llama inicialización por constructor. Esto está bien para inicializar atributos cuando creamos una instancia de una clase, pero qué si queremos cambiar más de una vez u obtener atributos, no podríamos hacerlo, aquí es donde entran en el juego los setters y getters.

Un getter es un método cuya función es retornar un determinado atributo, mientras que un setter es un método cuya función es recibir un valor por parámetro y asignarlo al atributo del objeto. Además, un getter siempre debe empezar por el prefijo get seguido del nombre del atributo, cuya primera letra será mayúscula, un setter siempre debe empezar por el prefijo set.

Comprendidos estos conceptos, rediseñamos nuestras clases Dog y Cat:

public class Dog { // lo mismo para Cat

    private String name;

    private String race;

    private String color;

    private float weight;

    public Dog() {

    }

    // constructor sobrecargado<br data-mce-bogus="1">

    public Dog(String name, String race, String color, float weight) {
        this.name = name;
        this.race = race;
        this.color = color;
        this.weight = weight;
    }

    public String getName() {
        return name;
    }

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

    public String getRace() {
        return race;
    }

    public void setRace(String race) {
        this.race = race;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public float getWeight() {
        return weight;
    }

    public void setWeight(float weight) { 
        this.weight = weight;
    }

    public void eat() {
        System.out.println("Estoy comiendo, jugamos más tarde");
    }

    public void bark() {
        System.out.println("Guarf! guarf!");
    }

    public void run() {
        System.out.println("Abran pasoooo");
    }

    public void sleep() {
        System.out.println("zZzZzZzZzZzZzZzZ");
    }

}

NOTA: Vemos como he declarado 2 constructores, uno sin parámetros y otro parametizado. Esto se conoce como sobrecarga de constructores y métodos. No cubriré esto porque se hace muy largo el post, pero en google pueden encontrar mucha información al respecto.

Ahora podemos inicializar los atributos de un objeto Dog en el momento de su instanciación o establecerlos más adelante:

public class Main {

    public static void main(String[] args) {

        Dog dog = new Dog("Firulais", "Bulldog", "Marrón", 15.4f);
        Cat cat = new Cat();
        cat.setName("Minino");
        cat.setRace("Angora");
        cat.setColor("Blanco");
        cat.setWeight(4.9f);

       System.out.printf("Nombre del perro: %s", dog.getName());
       System.out.printf("Peso del perro: %.2f", dog.getWeight());
       System.out.printf("Nombre del cato: %s", cat.getName());
       System.out.printf("Peso del gato: %.2f", cat.getWeight());
    }

}

Y tendremos la salida esperada, con los valores que les hemos establecido a los objetos Dog y Cat:

Nombre del perro: Firulais
Peso del perro: 15,40
Nombre del cato: Minino
Peso del gato: 4,90

Quizás te habrás dado cuenta de un pequeño problema, y lo hablaremos en el próximo post.

Nos vemos.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s