Introducción a la POO en Java

Nota: Esta entrada fue publicada el 22 dic de 2014 @ 21:38 en un blog que tenía anteriormente en Wordpress, y republicada aquí para el record.


Logo de Java

Estas vacaciones decidí adelantar la materia de Métodos de Programación II, en la que se ve la Programación Orientada a Objetos en Java, porque quería tomar una materia sencilla para mí que me subiera el promedio. La verdad es que todos estos conceptos ya los sabía desde antes, pero parece que mis compañeros tienen dificultades con ella, y como me están pidiendo ayuda, decidí crear esta serie de posts para explicarlos.

En este tutorial veremos algunos de los conceptos más básicos de la Programación Orientada a Objetos: objeto, clase, atributo, método, constructor; y llegaremos a crear el objeto de un carro. Comencemos pues, con una introducción a la POO.

¿Objetos? ¿Qué es eso?

Sí ya has programado antes, probablemente has usado int, double, char, float, etc. como tipos de dato, estos se llaman primitivos porque son los únicos tipos de dato que no son objetos (Java tiene 8 primitivos, además de los ya mencionados también están byte, short, long y boolean).

La necesidad de los objetos surge de que aveces queremos utilizar datos que no son solamente números. ¿Qué tal que quisiéramos tener un carro en el programa? Un carro no es un double ni un char, porque no es un solo dato sino que tiene varios atributos. Entonces para declarar un carro en el programa no sirve con sólo poner algo como

int carro = 1;

porque no es un número, es un objeto y debemos tratarlo como tal.

Las fábricas de objetos: clases y atributos

Sigamos con los carros. Si voy a una fábrica mecánica y les pido que me hagan el carro que quiero ¿me lo pueden hacer? Pues pueden solamente si tienen el plano de este, las instrucciones para fabricarlo.

Si tienen el plano de un carro pueden fabricar millones de carros a partir de este. Para crear un objeto en Java es lo mismo, se necesita tener un plano de dicho objeto y a partir de estos podemos fabricar todos los objetos que queramos de este tipo. Estos planos se llaman clases. Para definir cómo se fabrica nuestro objeto, debemos identificar primero sus característircas o atributos. En el caso de un carro, estos podrían ser

  • Fabricante (String).
  • Modelo (String).
  • Año (int).
  • Litros de gasolina (double).

Java exige que las clases estén en un archivo con extensión .java con el mismo nombre de la clase, y se recomienda que las clases comiencen con mayúscula, entonces nuestro archivo Carro.java para crear objetos Carro va quedando así:

public class Carro {
    String fabricante;
    String modelo;
    int anio;
    double ltGasolina;
}

Ya tenemos la clase con sus atributos. Ahora, para crear un objeto a partir de esta, se llama al método constructor, que es un método dentro de la clase con el mismo nombre de esta, sin tipo de dato de retorno (ni siquiera void), su función es recibir las características del objeto y asignarlas a los atributos.

public class Carro {
    String fabricante;
    String modelo;
    int anio;
    double ltGasolina;

    public Carro(String fabricante, String modelo, int anio, double ltGasolina) {
        this.fabricante = fabricante;
        this.modelo = modelo;
        this.anio = anio;
        this.ltGasolina = ltGasolina;
    }
}

De esta manera ya podemos crear cuantos carros queramos. Tal vez llame la atención la palabra this dentro del constructor, esta es necesaria en este caso porque el nombre de los parámetros es el mismo que el de los atributos, entonces para que no haya confusión se antepone this para hacer referencia a los atributos de este objeto.

Para crear un objeto a partir de la clase que creamos, simplemente escribimos en otro archivo Java lo siguiente:

Carro carro = new Carro("Nissan", "Quest", 2010, 20);

Tal vez parezca extraña esta sentencia, pero comparémosla con la definición de un entero:

int entero = 10;

En ambos casos, se pone primero el tipo de variable que queremos declarar: Carro (el nombre de la clase) en el primer ejemplo, int (el tipo de dato de los enteros primitivos) en el segundo.

Posteriormente, le damos un nombre a nuestra variable: la variable de tipo Carro se llama carro (nótese la diferencia de mayúsculas), mientras que la variable de tipo int se llama entero.

Por último, asignamos un valor a estas variables. En el caso del entero, como es un primitivo podemos simplemente asignarle una literal numérica 10; para carro, al ser objeto, tenemos que crear una instancia de este objeto, y esto se hace llamando al contructor, anteponiéndole la palabra new, que, como su nombre lo indica, crea un nuevo objeto a partir del constructor.

Los objetos realizan funciones

Ya tenemos definida nuestra clase, con sus propiedades, que puede crear objetos. Ya creamos un objeto llamado carro a partir de esta. Pero hasta ahora no hace mucho nuestro carro. Claro, podemos llamar a sus propiedades:

System.out.println(carro.modelo);

(Si declaramos el objeto carro tal y como está en el ejemplo de arriba, la línea anterior debería imprimir Quest).

Pero los objetos no sólo tienen propiedades, también realizan acciones. Por simplicidad, diremos que nuestro carro puede realizar dos acciones:

  • Recorrer distancia: Que toma una distancia a recorrer y reduce la gasolina (diremos que 1 Lt equivale a 1 Km, por simplicidad). Este método imprime cuántos kilómetros se recorrieron, y si hace falta gasolina imprime un mensaje.
  • Echar gasolina: Recibe una cantidad de litros de gasolina y los agrega a ltGasolina.

Las acciones, como podrá sospecharse, son solamente métodos públicos del objeto. Nuestra clase, pues, va quedando así:

public class Carro {
    String fabricante;
    String modelo;
    int anio;
    double ltGasolina;

    public Carro(String fabricante, String modelo, int anio, double ltGasolina) {
        this.fabricante = fabricante;
        this.modelo = modelo;
        this.anio = anio;
        this.ltGasolina = ltGasolina;
    }

    public void recorrerDistancia(int km) {
        if(km <= ltGasolina) {
            System.out.println("Se recorrieron " + km + " km.");
            ltGasolina -= km;
        } else {
            System.out.println("Hace falta gasolina para recorrer esa distancia.");
       }
    }

    public void echarGasolina(int lt) {
        ltGasolina += lt;
        System.out.println("Se echaron " + lt + " litros de gasolina al carro.");
    }
}

¡Nuestro objeto ya realiza acciones! Vamos a crear otro archivo de Java que contenga el main para poder usar usar nuestro objeto como es debido.

public class Programa {

    public static void main(String[] args) {
        Carro carro = new Carro("Ford", "F150", 2010, 1);
        System.out.println("Estas usando un " + carro.modelo + " de " + carro.fabricante + " anio " + carro.anio + " que tiene " + carro.ltGasolina + " litro(s) de gasolina.");
        carro.recorrerDistancia(1);
        carro.recorrerDistancia(1);
        carro.echarGasolina(3);
        carro.recorrerDistancia(3);
        carro.recorrerDistancia(1);
    }
}

Los dos archivos (Carro.java y Programa.java) deben estar guardados en el mismo directorio para que el programa funcione. Si corremos Programa.java debería imprimirse algo como esto:

Estas usando un F150 de Ford anio 2010 que tiene 1.0 litro(s) de gasolina.
Se recorrieron 1 km.
Hace falta gasolina para recorrer esa distancia.
Se echaron 3 litros de gasolina al carro.
Se recorrieron 3 km.
Hace falta gasolina para recorrer esa distancia.

¡Terminamos!

Hemos terminado con la creación de nuestro primer objeto. Siéntete libre de experimentar con este para ver qué sucede al modificarlo, también puedes agregarle más atributos y métodos para practicar:

  • Una característica de los carros es que tienen un color.
  • Los carros pueden ser pintados.
  • Puedes girar el carro.
  • Intenta crear varios objetos Carro distintos, llamar a sus métodos y ver qué sucede.
  • Hay carros que gastan más gasolina que otros.

Cualquier duda que tengas, puedes dejarla en los comentarios. Próximamente publicaré más tutoriales de conceptos de Orientación a Objetos.