Aula Macedonia


Curso de Programación Orientada a Objetos en C++


Artículo realizado por
Fernando Rodríguez.





Capítulo 2.
Fundamentos de la POO

¿Por qué la POO?

Seguro que muchos de vosotros os habreis preguntado unas cuantas veces qué es eso de la programación orientada a objetos, por qué todo el mundo no hace más que hablar de ella como la salvación de la ingeniería del software moderno, etc. Bien, la POO supone, bajo mi punto de vista, el único camino posible a seguir para la realización de programas en la actualidad. Para poder llegar a tal conclusión tan sólo debeís de fijaros en los requisitos que exije la realización de un proyecto de software en la actualidad.
Por un lado están las ingentes cantidades de información a tratar en todos ellos, por otro lado, el equipo de personas que intervienen es bastante numeroso y todos deben de poder utilizar el código que, el resto de miembros del equipo, han realizado sin tener que complicarse la vida. En tercer lugar, los programas actuales ocupan miles de líneas, con lo que no se puede programar a la ligera, hay que seguir unas reglas muy estrictas, que nos permitan construir programas robustos en cuanto al uso de sus estructuras de datos. Otro de los aspectos que hay que tener en cuenta es el de reutilización, cualquier programa ha de estar lo suficientemente bien diseñado para que las partes básicas del mismo puedan servir en la realización y construcción de otros, ya que no nos podemos permitir el "lujo" de estar perdiendo tiempo construyendo una y otra vez las mismas cosas. Hay que aprovecharse de código que ya está hecho.

Hasta aquí os he citado algunas de las características que exijen los proyectos de software de la actualidad. Negar alguna de ellas no es más que engañarse. Atrás quedaron los felices días en los que un programador podía abarcar un proyecto de software. El ejemplo más claro lo teneís en el campo de la programación de juegos. Antes bastaba con un programador, un grafista y ocasionalmente un músico para producir un sensacional juego, sin embargo, ahora para realizar un juego son necesario varios programadores que han de estar colaborando contínuamente, amén del resto de artistas que han de participar en la creación de la obra. Es por ello que no se puede acudir a la programación tradicional para la construcción de programas en la actualidad, ya que esta, no se diseño para dar soporte a grandes desarrollos de software con continuas actualizaciones y con multitud de equipos de desarrollo destinados a un campo específico del proyecto.

Y...¿por dónde van los tiros?

Vereis, la POO se basa en utilizar estructuras de datos en las que, tanto las variables como las funciones que manipulan dichas variables se encuentran unidas. Tan sólo teneis que imaginaros la definción de una estructura en C (struct). Todos sabéis que en las estructuras sólo es posible meter distintos campos que no son más que variables. Así podéis construir una estructura que tenga un campo de tipo entero (int) otro que sea de tipo caracter (char), arrays de un determinado tipo de dato, etc. Por otro lado, están las funciones que tratan a dichas estructuras de datos. En todo momento son "externas", esto es, cualquier funcion PUEDE (si cumple unas características obvias) acceder a un campo de una estructura y trabajar con él.
Pues bien, ahora imaginaros que teneis una estructura en la que están metidos no sólo los campos de variables de toda la vida, sino que, además, están metidas, también, las funciones para manipularlas, de tal modo que, sólo esas funciones que se encuentran metidas en la estructura, pueden manipular esas variables que, también, se encuentran en la estructura. ¿Ya os lo habeís imaginado?, si habeis podido pillar la idea, sabed que para poder crear una variable de dichas estructuras debereis de crear un OBJETO a dicha estructura, ¡sí!, los objetos no son más que variables o, mejor dicho, INSTANCIAS, a las estructuras, que a partir de ahora llamaremos CLASES, que poseen tanto variables como funciones para manipular dichas variables.

Bueno, si habeis logrado quedaros con que son los OBJETOS, INSTANCIAS y CLASES, teneis premio, ya que habeis logrado entender lo suficiente como para poder seguir con éxito. Si no has logrado pillar la idea de todo lo puesto más arriba, no te preocupes, se te irán aclarando a lo largo de los capítulos, pero te recomiendo que te vuelvas a leer lo de antes.

Los pilares de la POO

Después de presentaros una idea general de lo que supone la POO frente a la programación estructurada de toda la vida, os voy a comentar los pilares en los que descansa, esto es, las características que la hacen tan potente. Como vereís al acabar de leer este capítulo, la POO posee una serie de características estupendas para poder trabajar en equipo un proyecto de software, además de permitirnos construir programas envidiablemente robustos.

Encapsulación de datos.

La encapsulación de datos, no es más que la idea que expuesta más arriba, esto es, la idea de mezclar las variables y las fuciones que sirven para manipular dichas variables, en una misma estructura de datos.
Por ahora y hasta que no veamos las clases, quedaros con que todo esto se podría lograr, metiendo en una struct tradicional de C un campo destinado a las variables y otro a las funciones. Lógicamente, la posiblidad de meter funciones en la struct se la debemos al C++.
La encapsulación de datos, es fundamental en la POO, ya que nos permite construir objetos que, como ya se citó más arriba, no son más que instancias (o variables hablando mal) a dichas struct. Las ventajas que reporta la encapsulación de datos son estupendas, ya que nos permiten crear variables totalmente protegidas de posibles efectos no deseados, como cambio de valor por descuido o efectos laterales gracias a tener unas fuciones que se encargan de realizar todas las operaciones sobre ellas, es decir, no penseis que si os construis un objeto con sus propias variables vais a dar vosotros el valor a la variable directamente como se ha hecho toda la vida (que también se puede hacer). Lo que hareis será llamar a una función que lo único que que haréis será realizar dicha asignación.
Seguro que ahora mismo estais pensando que hacer eso es una estupidez, ¿para qué construir una función que haga, por ejemplo, a=b cuando yo mismo lo puedo hacer directamente?, la respuesta es bien sencilla, porque, precisamente en eso consiste la POO; al hacer eso estás ocultando información y evitando que tus variables puedan tomar valores no deseados, limando, en gran medida, fallos de paso de valores a las variables, tan comunes en la programación tradicional.
Pese a que todo esto es lo ideal, no os "asusteis". Como ya veremos, también podemos acceder a las variables que tengamos directamente, sin tener que llamar a una función que se encarge de ello, pero, como ya he intentado recalcar, esto se debe de evitar siempre.

Herencia

La herencia es otro de los pilares sobre los que descansa la POO. Gracias a la herencia, podemos hacer que todas las clases que tengamos, o las que nos interesen, puedan estar conectadas entre sí, aprovechando, unas de otras, diversas características básicas.
La idea de la herencia parte de poder tener un diseño en el que todo se vaya descomponiendo en módulos o problemas que van de lo más general a lo más específico y que a su vez, estén conectados entre sí. Quizás, este concepto va a quedar mejor explicado si se utiliza un ejemplo, así que vamos alla.

Imaginaros que se quiere construir una aplicación sobre las clases coche_turismo y coche_formula1. Para hacer esto mediante POO, tenemos 2 opciones, no utilizar la herencia o utilizarla. En caso de no utilizarla, bastaría con construir los objetos que de cada uno de los vehículos terrestres coche_turismo y coche_formula1, sin embargo, pese a que esta solución es válida, es bastante mala a la hora de utilizar las posiblidades que nos ofrece la POO, ya que se da pie a utilizar la herencia y no la utilizamos.
Fijémonos que tanto el coche_turismo como la coche_formula1 son vehículos terrestres y como tales tienen unas cosas en comunes y otras que no lo son. ¿Por qué no construir una clase que contenga aquellas variables o atributos comunes para que sean heredados por las clases coche_turismo y coche_fórmula1?. Esta es la solución más lógica, ya que, además de permitir un ahorro de memoria, clarifica todo de una forma bastante aguda.
Por todo esto, lo más lógico sería consturir una clase general que tuviera los atributos o variables acerca del tipo de ruedas, velocidad y tipo de motor. Esta claro que cualquier coche ya sea un turismo o de carreras disfruta de esos datos. Por otro lado, también habrá datos que serán específicos de la clase coche_turismo y de la clase coche_formula1, es decir, que habrá datos que pueda tener uno y no los tenga el otro. El caso más claro es el de pasajeros. Mientras un turismo puede llevar pasajeros, un coche de fórmula 1 no puede llevar pasajeros (a parte del conductor, claro), es por esto, que podríamos meter, y así hemos hecho, una variable de ese tipo en la clase coche_turismo.
Como todo esto de la herencia queda mejor con un gráfico ahí va lo que os quiero decir mediante el ejemplo descrito:



En el ejemplo de arriba sólo he tratado para un par de clases pero, como veremos en sucesivos capítulos, la herencia nos permitírá construir perfectas jerarquías de clases que nos ayudarán a partir de una idea general y llegar a algo concreto y de fácil tratamiento.

Pese a que la POO descansa sobre otros importantes pilares, quizás será demasiado prematuro hablaros de ellos ahora, lo importante es que se vaya cogiendo una idea general con lo visto en este capítulo. Saber que es un objeto y que una clase, así como las características y ventajas que aporta una encapsulación de datos y funciones junto a la posiblidad de desglosar nuestros problemas a modo de jerarquías mediante herencias, son cosas suficientes como para ir haciendose una idea de los mecanismos de la POO.
En los sucesivos capítulos, ya nos meteremos "más a fondo" y pondremos listados y ejemplos en código C++.




AULA MACEDONIA
a
MACEDONIA Magazine