PROGRAMACION ORIENTADA A OBJETOS(POO)

Programación OO(POO)
La programación orientada a Objetos básicamente define una serie de conceptos y técnicas de programación para representar acciones o cosas de la vida real basada en objetos, a diferencia de otras formas de programación como por ejemplo la estructurada, con la POO trabajamos de manera distinta vinculando diferentes conceptos tales como clases, objetos, métodos, propiedades, estados, herencia, encapsulación entre otros, generando cada vez interrelaciones en nuestro desarrollo en pro del funcionamiento del sistema principal, definiendo el programa como un conjunto de estos objetos relacionados entre si.

Veamos algunos de los conceptos principales.....



4 Pilares de la POO



1. Abstracción

La abstracción consiste en llevar la representación y comportamiento de una entidad en el mundo real a un ámbito explícito que se pueda representar en la programación. Generalmente esto lo vamos a representar en un contenedor general llevado a cabo por una clase.
2. Encapsulamiento
Esta parte tiene el fin de mantener segura la información de una entidad abstraida, con lo que se crean atributos de la entidad del mundo real como variables privadas para un uso exclusivo de la clase mientras que existirá otra parte que brindará un acceso público a través de métodos de lectura y escritura.


Se representa por 3 niveles :




Público: Se puede acceder a todos los atributos o métodos de la clase. Protegido: Se puede acceder a los atributos o métodos solo en la misma jerarquía de herencia. Privado: Solo se puede acceder a los atributos o métodos de la clase en la que se encuentran.


Con la Encapsulación mantenemos nuestros datos seguros, ya que podemos evitar que por ejemplo se hagan modificaciones al estado o comportamiento de un objeto desde una clase externa, una buena practica es trabajar con métodos setter y getter que permiten manipular nuestros datos de forma segura.

en Java lo representamos así:













3. Herencia

Tal como su nombre lo indica, esto consiste en heredar atributos y/o acciones (Métodos) desde una clase a otra con lo que podemos reducir redundancias en el código y escalar de forma reutilizable nuestra aplicación de software.


Básicamente mediante este concepto podemos obtener las características de una clase padre o de una jerarquía mayor dependiendo de nuestro árbol de herencia, en java definimos esta jerarquía mediante la palabra extends seguido del nombre de la clase a la que vamos a heredar, también se debe tener claro que solo se puede heredar de una sola clase pues el lenguaje no permite la Herencia múltiple (En Java por defecto todas las clases heredan de la clase Object, es decir, esta es la clase Padre de todas las clases en Java).

Antes de continuar, les comparto este video donde podràn complementar el concepto mediante otro ejemplo practico diferente al de esta entrada... 
Requisitos.

Lo único que necesitamos para hacer el ejemplo practico es un entorno de desarrollo, conocer los conceptos de POO (vistos en la entrada anterior) y ganas de continuar :P para este caso usaremos el IDE Eclipse...........Empecemos.

El Ejemplo.

Conociendo el concepto de clases y objetos vamos a asumir que necesitamos construir una aplicación sobre los diferentes tipos de vehículos existentes, pero para esto necesitamos clasificarlos, en este caso trabajaremos con vehículos acuáticos y aéreos.

Teniendo como punto de partida la información anterior podemos empezar a definir nuestras clases, vamos a trabajar con vehículos acuáticos y vehículos aéreos, entonces......... cual es el factor común de estos 2 tipos?..............................................

El factor común es que sin importar si es un avión o un barco, estamos hablando de vehículos, y ambos pueden compartir características comunes por esta razón la Clase principal de nuestro sistema será la clase Vehiculo.

Partiendo de lo anterior podemos profundizar aun mas en nuestro árbol de herencia, sabemos que un barco o un avión son vehículos, pero será que esta información es suficiente???.......... sería correcto decir que ¿un barco es igual a un avión porque ambos son vehículos?..........definitivamente NO, ya que si bien descienden del mismo concepto de vehículo ambos tienen características propias que los diferencian, aquí es donde tenemos que pensar de forma general para poder definir un correcto árbol de herencia, por eso podemos decir que un barco además de descender de un vehículo, también desciende del tipo de vehículos Acuáticos los cuales tienen un conjunto de características comunes para cualquier vehículo acuático (sin olvidar que cada vehículo acuático puede tener sus características propias) y de la misma forma un avión desciende del tipo de vehículos Aéreos (con la misma lógica del anterior)............tenemos así nuestras clases Acuático y Aéreo que a su vez descienden de la clase Vehículo, y son padres de cualquier vehículo en su jerarquía.

Al final tenemos definida nuestra estructura de clases (para este ejemplo no entraremos en detalles sobre las características a profundidad de cada clase, pero si alguna básica para resaltar el concepto) así:



Como vemos, la Clase Padre es Vehículo, la cual tiene como hijas a las clases Acuático y Aéreo, estas a su vez son clases Padre de BarcoVeleroAvión y Helicóptero que a la vez son nietas de Vehículo...Simple o ¿no?


Con esto ya tenemos una jerarquía de herencia definida, esto quiere decir que por ejemplo la clase Avión puede usar el método volar() de la clase Aéreo, así como también usar el método transportar() de la clase Vehículo, pues se encuentra en el mismo árbol de herencia, sin embargo no puede usar el método navegar() de la clase Acuático, ya que no es de tipo Acuático.

Teniendo nuestro diagrama definido, vamos a aplicar el concepto en Java.

Vehiculo.
Clase Padre.


Acuatico.
SubClase extiende de Vehiculo.

Aereo.
SubClase extiende de Vehiculo.

Barco.
SubClase extiende de Acuatico.


Velero.
SubClase extiende de Acuatico.

Clase Avion.
SubClase extiende de Aereo.



Clase Helicoptero.
SubClase extiende de Aereo.


Como vemos seguido del nombre de la clase se tiene la palabra extends la cual indica que se extiende o hereda de la clase definida, así mismo todas las clases tienen al menos un método que representa la característica propia de la clase, para las clases hijas ese método define el proceso que solo ellas pueden realizar, para las clases padre, ese método define el proceso que es común o general para las clases hijas.

Ahora veremos como funciona la herencia en nuestra aplicación.

Creamos una clase Principal donde se realizarán las operaciones, podemos crear instancias de las clases y verificar el nivel de acceso que tenemos a las características tanto de nuestra clase como de nuestra Jerarquía de Herencia, así.


En la imagen vemos que tenemos una instancia de la clase Vehículo, esto lo podemos traducir como la creación del objeto miVehiculo de tipo Vehiculo, no olvidemos que esta clase es la clase padre, por eso al verificar los métodos disponibles (En Eclipse después del punto hacemos Ctrl+espacio) vemos que nos aparecen las características propias de la clase, asi como otros métodos de la clase Object (Recordemos que en java todas las clases heredan de Object) que también podemos usar.


Al crear otro objeto de la clase Acuatico y realizar el mismo proceso anterior, vemos que ahora tenemos no solo los métodos propios de la clase sino también los métodos y atributos de la clase Vehiculo.

Ahora miremos un objeto de las clases Hijas.


Al crear un objeto de la clase Barco vemos que ahora no solo tenemos las características de Barco sino también podemos hacer uso de las características de Acuatico y de Vehiculo.

Este mismo principio aplica para la otra parte de nuestra jerarquía (Vehículos Aéreos) donde como mencionamos anteriormente solo podemos acceder a los métodos y atributos disponibles para ese árbol de herencia.

Veamos todo nuestro código...

Con este ejemplo hacemos el llamado a los métodos tanto propios como heredados de las clases padres, obteniendo el siguiente resultado.


Como vemos podemos acceder a los diferentes métodos desde otras clases, y si nos fijamos bien podemos identificar que siempre usamos la misma propiedad nombreVehiculo de la clase Vehiculo, lo hicimos usando objetos diferentes por tal razón el valor de la propiedad depende del asignado por cada objeto, convirtiéndose en un atributo del objeto y no de la clase como tal.


Conclusión

Podemos ver que la herencia va ligada a muchos otros conceptos, vimos el concepto de clase, el concepto de objetos entre otros, en este caso también es importante conocer el concepto de encapsulación ya que como compartimos características entre clases tenemos que estar seguros que la clase que accede puede usarlas


4. Polimorfismo
El nombre viene dado por el hecho de que esto se comportará de varias formas. Se basa en el concepto de herencia para posteriormente realizar instancias de una clase hijo dentro de una clase padre con lo que al compartir acciones o métodos estos se cargarán con la definición del hijo pero como se mencionó antes, es decir sobre el padre y así de esta manera una misma clase padre podría tener dos o más diferentes instancias de cada hijo con lo que obtendríamos los mismos métodos dentro de dicho padre pero con diferentes comportamientos.

Este tal vez sea uno de los conceptos de la programación orientada a objetos mas usados pero muchas veces sin saber que se aplica ya que el concepto inicialmente puede ser un poco confuso, básicamente mediante el polimorfismo programamos de forma general en lugar de hacerlo de forma especifica, se usa cuando se trabajen con la herencia y objetos de características comunes los cuales comparten la misma superClase y árbol jerárquico, al trabajar con este concepto optimizamos y simplificamos en gran medida nuestro trabajo.

básicamente podemos definirlo como la capacidad que tienen los objetos de comportarse de múltiples formas sin olvidar que para esto se requiere de la herencia, en si consiste en hacer referencia a objetos de una clase que puedan tomar comportamientos de objetos descendientes de esta.


con el polimorfismo usamos la generalización olvidando los detalles concretos de los objetos para centrarnos en un punto en común mediante una clase padre.

Tomando como ejemplo la imagen anterior, podemos decir que un objeto de la clase FiguraGeometrica puede usarse para referirse a cualquier objeto de cualquier subClase de FiguraGeometrica.............. en otras palabras una figura geométrica puede ser un cuadro, un triángulo, un cuadrado o cualquier figura que en términos generales sea geométrica.....

Veamos este proceso como se representa en Java.

Como vemos en el ejemplo la clase FiguraGeometrica puede convertirse en cualquier figura que se encuentra en su jerarquía de Herencia pudiendo utilizar las propiedades que compartan entre ellas, hay que tener presente que solo se permite el polimorfismo de clases padre a clases hija mas no al contrario
 (VIDEO explicado)https://www.youtube.com/watch?v=lBnbUazXeKo#action=share

CLASE

Una clase es una plantilla que define las variables y los métodos que son comunes para todos los objetos de un cierto tipo.

Las clases son uno de los principales componentes de un lenguaje de programación, pues en ellas ocurren todos los procesos lógicos requeridos para un sistema, en si podemos definirlas como estructuras que representan objetos del mundo real, tomando como objetos a personas, lugares o cosas, en general las clases poseen propiedades, comportamientos y relaciones con otras clases del sistema. 

una clase se compone por tres partes fundamentales:

Nombre : Contiene el Nombre de la Clase.
Atributos : Representan las propiedades que caracterizan la clase.
Métodos : Representan el comportamiento u operaciones, la forma como interactúa la clase con su entorno.

En java se representa así :


De este modo podemos definir una plantilla de variables y métodos para todas las bicicletas. Las plantillas para crear objetos son denominadas clases.

QUÉ ES UN OBJETO EN JAVA
Un objeto no es más que un conjunto de variables (o datos) y métodos (o funciones) relacionados entre sí. Los objetos en programación se usan para modelar objetos o entidades del mundo real (el objeto hijo, madre, o farmacéutica, por ejemplo). Un objeto es, por tanto, la representación en un programa de un concepto, y contiene toda la información necesaria para abstraerlo: datos que describen sus atributos y operaciones que pueden realizarse sobre los mismos.
Al igual que las clases se componen de tres partes fundamentales:

Estado: Representa los atributos o características con valores concretos del objeto.
Comportamiento: Se define por los métodos u operaciones que se pueden realizar con él. 
Identidad: Es la propiedad única que representa al objeto y lo diferencia del resto.

en la imagen, los moldes representan las clases, mientras que las galletas obtenidas de estos moldes representan los objetos instancias de estas clases, por ejemplo atributos del objeto galleta podría ser sabor, color, tamaño etc.

En java se representa creando una instancia de la clase por medio de la palabra new al hacer eso creamos el objeto de la clase y podemos hacer uso de los métodos o atributos de esta (dependiendo de la visibilidad de los mismos ) por medio de un punto (.) así:

·       Atributos
Los atributos son las caracterísiticas individuales que diferencian un objeto de otro y determinan su apariencia, estado u otras cualidades. Los atributos se guardan en variables denominadas de instancia, y cada objeto particular puede tener valores distintos para estas variables.
Las variables de instancia también denominados miembros dato, son declaradas en la clase pero sus valores son fijados y cambiados en el objeto.
Además de las variables de instancia hay variables de clase, las cuales se aplican a la clase y a todas sus instancias. Por ejemplo, el número de ruedas de un automóvil es el mismo cuatro, para todos los automóviles.
·       Métodos
Los métodos son un conjunto de instrucciones definidas dentro de una clase, que realizan tareas y, por norma general, operan sobre los estados de los atributos de dicha clase.
Así mismo, los métodos son el mecanismo que implementa la comunicación entre objetos, lo que comúnmente se llama Paso de Mensajes.
Un objeto, el emisor, solicita ejecutar uno de sus métodos a otro objeto, con el objetivo de que este realice alguna acción, o devuelva cierta información.
Los métodos así mismo, siguen la misma estructura que las funciones y procedimientos de la programación estructurada y pueden recibir, o no, parámetros, así como devolver, o no, valores.

·       Modificadores de acceso
Entenderemos los modificadores de acceso Java como un conjunto de palabras clave de Java que nos permiten controlar la visibilidad de los objetos (Clases), estado (Propiedades) y funcionalidades (Métodos) de una aplicación desde otras partes de la misma. Este control de acceso que normalmente se realiza en lenguajes orientados a objetos se llama encapsulamiento.
Los modificadores de acceso se pueden aplicar a clases, propiedades y métodos. Son los siguientes:

1.   public: El método, propiedad o clase es accesible desde cualquier parte de la aplicación.
2.   private: El método o propiedad es accesible sólo desde la clase en la que se encuentra. En caso de una clase, sólo las “inner classes” pueden ser privadas, ya que no tiene sentido definir una clase de primer nivel privada si nadie pudiera luego acceder a ella.
3.   protected:  El método es accesible por código que esté dentro del mismo paquete y subclases (aunque estas esten en otro paquete)
4.   Sin especificar: Cuando no especificamos ningún modificador de acceso se aplica el “por defecto”, este tiene la misma función que el anterior sin que entren en juego las subclases. Sólo permite el acceso a ese código desde dentro del mismo paquete. (También se conoce como package-private, que es más fácil de recordar)
Encapsulamiento
El encapsulamiento concretamente se preocupa de mantener las propiedades de las clases inaccesibles desde fuera (a través de la palabra clave private), para hacerlas accesibles posteriormente a base de métodos accesibles desde fuera (public, package o sin definir ningún modificador de acceso) evitando el uso de esas propiedades directamente y promoviendo el uso de  las mismas a partir de métodos.

Clases Abstractas
clase hombre, humano entre otras, pero obviamente vemos que la imagen no tiene elementos como ojos, nariz, boca, rostro en general, ni dedos, pies, manos o cuello....... pero entonces porque decimos que es una persona?.........Precisamente aquí estamos aplicando el concepto de abstracción, ya que nos fijamos en lo mas representativo de algo, en este caso vemos que se tiene una cabeza, tronco, brazos y pies, con esto es suficiente para saber que es una persona sin fijarnos en los detalles mencionados anteriormente.
Las clases abstractas permiten crear métodos generales con un comportamiento común para otras clases concretas sin importar sus características ni el comportamiento que usen para dichos métodos.

La Abstracción en java solo tiene lógica mediante la Herencia, ya que una clase abstracta posee al menos un método abstracto el cual no tiene implementación, el comportamiento de estos métodos lo definen las clases concretas que lo hereden.
Podemos usarlos cuando existan varias clases con características o acciones comunes pero con diferentes comportamientos..............mediante el uso de la herencia y componentes abstractos hacemos mas óptima y organizada nuestra aplicación. (hay que tener en cuenta que a diferencia de las clases concretas, las clases abstractas no se pueden instanciar).

Bueno, continuando Básicamente una clase Abstracta es similar a una clase normal, la estructura es prácticamente igual, ya que poseen nombre, atributos y métodos pero para que una clase sea abstracta la condición es que al menos uno de sus métodos sea abstracto (se le agrega la palabra reservada abstract y no se especifica el cuerpo del método).................su uso depende de la aplicación del concepto de Herencia y adicionaremos a la estructura básica de clase la palabra reservada abstract.

Veamos como se implementa en Java.



Características de una Clase Abstracta:

Esto es lo que debemos conocer sobre de Clases Abstractas. 
·       Una clase Abstracta No puede ser instanciada (no se pueden crear objetos directamente - new ), solo puede ser heredada. 
·       Si al menos un método de la clase es abstract, esto obliga a que la clase completa sea definida abstract, sin embargo la clase puede tener el resto de métodos no abstractos.
·       Los métodos abstract no llevan cuerpo (no llevan los caracteres {}). 
·       La primer subclase concreta que herede de una clase abstract debe implementar todos los métodos de la superclase.

¿Cuando Utilizarlas?.

Al trabajar clases y métodos abstractos, no solo mantenemos nuestra aplicación mas organizada y fácil de entender sino que también al no poder instanciar una clase abstracta nos aseguramos de que las propiedades especificas de esta, solo estén disponibles para sus clases hijas....

Con las Clases Abstractas lo que hacemos es definir un proceso general que luego sera implementado por las clases concretas que hereden dichas funcionalidades..........¿Que?........... es decir, si tengo una clase que hereda de otra Abstracta, estoy obligado a poner en el código, todos los métodos abstractos de la clase padre, pero esta vez serán métodos concretos y su funcionalidad o cuerpo sera definido dependiendo de para que la necesite, de esa manera si tengo otra clase que también hereda del mismo padre, implementaré el mismo método pero con un comportamiento distinto..........Veamos un Ejemplo.



En el diagrama vemos una clase Abstracta Instrumento, la cual posee una propiedad tipo y un método abstracto tocar(), vemos también las clases hijas GuitarraSaxofon y Violin que para este ejemplo solo utilizaremos (mediante la herencia) las propiedades de la clase Padre.

Todos los instrumentos musicales se pueden tocar, por ello creamos este método abstracto, ya que es un proceso común en todos los instrumentos sin importar el detalle de como se tocan, pues sabemos que una guitarra no se toca de la misma manera que el saxofón, así al heredar de la clase Instrumento, todas sus clases hijas están obligadas a implementar este método y darle la funcionalidad que le corresponda...

veamos esto en Java.


Como vemos cada una de las clases concretas implementan el método tocar() y le dan la funcionalidad dependiendo de como se toque el instrumento, también en cada constructor de las clases definimos el tipo, pero si nos fijamos bien en las clases concretas no tenemos la variable tipo declarada, pues estamos usando la variable heredada de la clase Instrumento.



Hay que tener en cuenta que cuando trabajamos con clases Abstractas, estas solo pueden ser heredadas mas no instanciadas, esto quiere decir que no podemos crear objetos directamente de estas clases.

Como vemos en la clase Principal tenemos la lógica para ejecutar nuestra aplicación y usamos el concepto de Polimorfismo para crear los objetos de tipo Instrumento por medio de sus clases Hijas, pero en ningún momento creamos un objeto como instancia directa de la clase abstracta

Interfaces en Java

Como sabemos en Java no existe la herencia múltiple, pudiendo heredar solamente de una clase, las Interfaces son una gran herramienta para simular este concepto......

En esta entrada describiremos un poco sobre lo que son las interfaces, sus principales características y veremos un diagrama que nos puede colaborar para su mejor entendimiento...

Para empezar debemos saber que una Interface es una Clase completamente Abstracta, como regla, sabemos que las clases abstractas poseen como mínimo un método abstracto, pero hablando de una interface, todos sus métodos tienen que serlo...
Como vimos en la entrada sobre conceptos básicos, las interfaces muchas veces son definidas como un tipo de contrato entre las clases concretas que la implementen, ya que la clase que lo haga se encuentra obligada a definir los métodos abstractos que la componen. 
Lo anterior quiere decir que cuando creamos un Interface, lo que hacemos es definir lo que la clase que la implemente podrá hacer, pero no indicamos la forma en que lo hará.

¿Herencia Multiple?
Podemos decir que las interfaces simulan la herencia múltiple ya que una clase puede implementar cualquier numero de interfaces, además las interfaces pueden heredar uno o mas números de interfaces mediante la palabra extends, pero jamas podrán heredar clases concretas...

En java se usa la palabra reservada implements para indicar que implementamos una interface, la estructura general de una clase que implementa una interface es la siguiente.



Vemos que la clase Principal implementa 3 interfaces, por eso decimos que simulan la herencia múltiple ya que heredamos los métodos que nos brindan..............veamos en general las principales características.

Características de las Interfaces.

·       Todos los métodos de una interfaz son implícitamente public abstract, no es necesario especificarlo en la declaración del mismo.
·       Todas las variables y atributos de una interfaz son implícitamente constantes (public static final), no es necesario especificarlo en la declaración del misma
·       Los métodos de una interfaz no pueden ser: static, final, strictfp ni native.
·       Una interfaz puede heredar (extends) de una o más interfaces.
·       Una interfaz no puede heredar de otro elemento que no sea una interfaz.
·       Una interfaz no puede implementar (implements) otra interfaz.
·       Una interfaz debe ser declarada con la palabra clave interface.
·       Los tipos de las interfaces pueden ser utilizados polimórficamente.
·       Una interfaz puede ser public o package (valor por defecto). 
·       Los métodos toman como ámbito el que contiene la interfaz.
 Algunas de las anteriores características se verían así.




Como vemos las anteriores son algunos ejemplos de la forma de declarar atributos o métodos, cualquiera de las opciones anteriores es valida....

Hay que tener presente algo, ya vimos que tanto para clases Abstractas como para Interfaces la herencia es permitida, pero por ejemplo para este tipo componentes, si una interface hereda de otra, esta no está obligada a implementar los métodos que posee la Interface padre, ya que la implementación tanto de los métodos de la clase padre como de la interface que los hereda depende de la clase concreta que implemente dicha interface........ este principio también aplica a las clases Abstractas, si una clase abstracta implementa una interface, los métodos de esta no necesariamente se deben implementar en la clase Abstracta, pero si se tienen que implementar en la clase concreta que herede de la clase abstracta....


¿Cuando Utilizarlas?
Su uso esta muy ligado al concepto de herencia y cumple el mismo principio que aplicamos al usar clases abstractas, lo que buscamos es establecer un mecanismo donde podamos compartir características comunes entre clases diferentes, además al igual que con clases abstractas nos aseguramos que los métodos y atributos solo están disponibles para las clases que las implementen...

Veamos un Ejemplo.



En el diagrama de clases vemos 6 clases concretas y 2 interfaces, las clases Humano y Animal son clases padre de "Hombre y Mujer" y "Perro y Gato" respectivamente, ahora bien, Humano y Animal son clases diferentes con un árbol de herencia marcado, pero ambas poseen características comunes que podemos usar por medio de la interface AccionesGeneral.

Podemos decir que tanto un Hombre como un Gato pueden caminar, usando para esto el método desplazarse(), donde cada clase dará el mecanismo de desplazamiento, por ejemplo el hombre lo hace en 2 piernas mientras que el gato en 4 patas (o dependiendo de la forma como lo realicen), y este mismo concepto puede aplicarse a los otros métodos enmarcados en la Interface AccionGeneral que tanto Humanos como Animales comparten.

También tenemos la interface AccionesHumano para esos métodos o características que solo son aplicables a los humanos y que tanto Hombre como Mujer pueden adoptar, así la clase Humano podrá simular la herencia múltiple al implementar las 2 interfaces mencionadas.

Y listo!!! Básicamente esta es la lógica detrás de las Interfaces, Los invito a desarrollar este ejemplo en Java aplicando la estructura de interface explicada anteriormente y similar al ejemplo tratado en la entrada sobre Clases Abstractas....


API DE JAVA

¿QUÉ ES Y PARA QUÉ SIRVE EL API DE JAVA?
Hasta ahora hemos visto ejemplos donde utilizábamos la clase System (por ejemplo en la invocación System.out.println) o la clase String (que es la clase gracias a la que podemos usar los objetos String). ¿De dónde salen estas clases si nosotros no las hemos programado como la clase Taxi o la clase Exponenciador?
 
La respuesta está en que al instalar Java (el paquete JDK) en nuestro ordenador, además del compilador y la máquina virtual de Java se instalan bastantes más elementos. Entre ellos, una cantidad muy importante de clases que ofrece la multinacional desarrolladora de Java y que están a disposición de todos los programadores listas para ser usadas. Estas clases junto a otros elementos forman lo que se denomina API (Application Programming Interface) de Java.


Comentarios

Entradas populares de este blog

ACTIVIDAD 1