La programación orientada a objetos (POO o sus siglas en ingles OOP) es un “estilo” (paradigma) de programación. Donde todo se comporta como un objeto, es decir, se hace una abstracción de un concepto y se lleva a código fuente.

El concepto de abstracción es muy importante entenderlo ya que es la base de la programación orientada a objetos. Consiste en aislar un objeto de su contexto, e identificar este objeto ¿que hace?, ¿como lo hace? y ¿para que lo hace?. Estas preguntas se resuelven haciendo una análisis del sistema y llevándolo a modelos de código, donde se expresan las características del objeto deseado.

Durante este análisis (abstracción) se identifican las características esenciales y las no esenciales, esto con el fin de generar la representación en código.

ahora veamos los conceptos por los que esta compuesto la forma de trabajo orientada a objetos.

Clase

Una clase es la abstracción de un objeto/concepto concreto, que tiene tiene propiedades(atributos) y realiza algunas acciones(funciones o métodos) y se pueden crear uno o mas copias de este a partir de un modelo.

Vamos a ver como esta compuesto. Para ejemplificar y que quede mas claro los conceptos vamos a usar el típico ejemplo de una fabrica de vehículos. Supongamos que queremos construir un carro.

Atributo

Un atributo es una característica propia de una clase, por ejemplo, en el caso del carro los atributos pueden ser color, cantidad de ruedas, material, etc.. (podemos listar N cantidad de atributos, siempre y cuando sean necesarios para la descripción o funcionamiento de la clase).

Método

Un método es una acción que realiza nuestra clase. Netamente en programación es una porción de código encapsulado que se ejecuta en respuesta a alguna llamada, interacción u otra acción(método). Por ejemplo, en nuestro carro, algunos eventos pueden ser: encender, acelerar, frenar…

El termino de encapsulamiento es muy importante en la programación orientada a objetos, ya que todo nuestro código debe ir correctamente estructurado, y los métodos deben ser concretos y bien definidos (Para profundizar en código limpio te dejo este post). El encapsulamiento se refiere a la agrupación de elementos propios con el objetivo de crear un mayor nivel de cohesión y reutilización del código.

En alguna literatura y arquitecturas de trabajo tenemos una separación(clasificación) de estos métodos en métodos, funciones y eventos, pero por lo general usaremos método o función para referirnos a lo mismo.

Con estos conceptos ya podemos plantear un ejemplo completo de nuestra clase carro, así que lo pasaremos a código. Utilizare C# para hacer el ejercicio con código, aplicado a un proyecto de consola. Podríamos utilizar cualquier otro lenguaje que soporte este paradigma, yo elijo este simplemente por que la lectura de código se me hace muy sencilla y así todos podemos ver y entender los ejemplos un poco mejor.

class Vehiculo
{
    private string color;
    private int cantidadRuedas;
    private string material;

    public void encender()
    {

    }

    public void acelerar()
    {
    }

    public void frenar()
    {

    }
}

En el anterior ejemplo de código podemos ver la construcción de la clase vehículo, en donde le asignamos algunos atributos y métodos. Podemos ver que estamos usando unas palabras clave antes de declarar un atributo o método(private, public). No entrare a explicar como usarlas en este lenguaje, si no que daré una definición general, aplicable a cualquier lenguaje. Estas palabras nos indican el alcance(scope) de un atributo, método u objeto. ¿Qué quiero decir con alcance?,  pues el nivel de visibilidad dentro del contexto. Es decir a que tiene acceso el contexto de un objeto. Aquí entramos a otro concepto fundamental de la programación orientada a objetos, el principio de ocultación. Esto quiere decir que cada objeto esta ligado a su propio contexto y aislado para el resto del entorno. Por ejemplo en nuestra clase vehículo, seria publico el color del carro, pero, por ejemplo, la marca del motor, no queremos que todos la conozcan, por lo que seria privado, o protegido. Este principio aplica para todos los objetos con los que se trabaje.

En el ejemplo de código anterior dejé los atributos como privados, si queremos exponerlos utilizaremos una función GET(obtener valor) o SET(asignar valor) para por medio de ellas tener acceso a este valor.

Hemos hablado bastante de los objetos e hicimos un ejemplo de la declaración de una clase. No hay que confundir objeto y clase, son términos totalmente diferentes. Un objeto es la instancia de una clase. Es decir, la clase anterior es nuestro modelo abstracto y una instancia de este objeto seria un vehículo como tal. Veamos un ejemplo de la creación de un objeto de tipo vehículo con código.

    Vehiculo modelo1 = new Vehiculo();
    Vehiculo modelo2 = new Vehiculo();
    Vehiculo modelo3 = new Vehiculo();

Hemos creado varias instancias(objetos) de la clase vehículo, ahora hagamos algunos experimentos.

Antes de continuar aclaro que a nuestra clase Vehiculo le agregue los getters y setters para trabajar con los atributos, a continuación voy a colocar un ejemplo para el atributo color, pero recuerden que el proyecto completo lo puedes bajar desde Github por medio del enlace que esta al final de este post.

public string getColor()
{
     return this.color;
}

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

En la mayoría de lenguajes lo pueden hacer de esta manera, pero en el código completo también encontraran otro modo para hacerlo con una notación propia del lenguaje.

Bueno ahora si continuemos. Creamos tres vehículos, a cada uno vamos a asignarle las ruedas, un color y un material. Finalmente imprimimos en pantalla el color de cada uno.

modelo1.cantidadRuedas = 4;
modelo2.cantidadRuedas = 4;
modelo3.cantidadRuedas = 4;

modelo1.setColor("Rojo");
modelo2.setColor("Amarillo");
modelo3.setColor("Azul");

modelo1.material = "Aluminio";
modelo2.material = "Plastico";
modelo3.material = "Fibra De Carbono";

Console.WriteLine(modelo1.getColor());
Console.WriteLine(modelo2.getColor());
Console.WriteLine(modelo3.getColor());

Tenemos en este momento una clase Vehiculo, con la cual hemos creado tres carros, pero si lo pensamos bien podemos crear otro tipo de vehículos, como una bicicleta, moto u otro tipo de vehículo sobre ruedas.

Así que vamos a tocar otro pilar de la programación orientada a objetos.

Herencia

Aunque las clases se crean para estar aisladas de un contexto, estas se deben relacionar con otras, para así dar sentido y funcionalidad a ese contexto. Este concepto podemos entenderlo como una relación padre-hijo, donde el hijo hereda propiedades y características del padre, dependiendo del scope que tengan estas características definidas. El hijo no puede heredar ninguna característica que este como privada en el padre. Veamos el código, agregare dos clases para mostrar como funciona la herencia.

class Carro : Vehiculo
{
    public Carro()
    {
        this.cantidadRuedas = 4;
        this.setColor("Dorado");
        this.material = "Hierro";
    }

    public Carro(string color, string material)
    {
        this.cantidadRuedas = 4;
        this.setColor(color);
        this.material = material;
    }
}
class Bicicleta : Vehiculo
{
    public Bicicleta()
    {
        this.cantidadRuedas = 2;
        this.material = "Aluminio";
        this.setColor("Cromado");
    }

    public Bicicleta(string color)
    {
        this.cantidadRuedas = 2;
        this.material = "Aluminio";
        this.setColor(color);
    }
}

Podemos hablar de otro termino viendo el ejemplo, y son los constructores, no son propios de la programación orientada a objetos, pero se están convirtiendo en un estándar para todos los lenguajes que apuntan a este paradigma. Acerca de este tema solo voy a decir que el constructor es un método que se caracteriza por tener el mismo nombre de la clase y es el encargado de inicializar la instancia de la clase.

Un tema mucho mas importante, y que si es propio de este paradigma es el concepto de polimorfismo, este atributo de la programación orientada a objetos nos permite crear varios métodos con el mismo nombre pero que se comporten de manera diferente dependiendo de los parámetros que recibe. En el código anterior podemos ver el ejemplo, donde construí dos constructores para cada clase y así ilustrar esta característica. También lo podríamos hacer con cualquier otro método.

Hemos revisado el concepto de herencia y ahora podemos segmentar nuestra aplicación en diferentes clases con cierta relación, esto nos lleva a otro principio de la programación orientada a objetos. La modularidad, que se refiere a la capacidad de separar estas clases y agruparlas en módulos, es decir secciones que comparten un mismo contexto.

Por ultimo nos queda un ultimo termino que ver, este es la recolección de basura, que se refiere a la capacidad del lenguaje de eliminar de memoria los objetos que ya no se van a usar. La mayoría de lenguajes que usan este paradigma lo hacen de manera automática.

Y esto es todo amigos… Dejamos por aquí esta introducción a POO, espero les halla sido de mucha utilidad, recuerden dejar sus comentarios y preguntas. El código completo esta Github y puedes acceder directamente por el enlace que dejo continuación.

[DISPLAY_ULTIMATE_PLUS]