Está en la página 1de 83

UNIVERSIDAD DE LA AMAZONIA

FACULTAD DE INGENIERIA
DEPARTAMENTO DE EDUCACIÓN A DISTANCIA

PROGRAMA
TECNOLOGÍA EN INFORMÁTICA Y SISTEMAS

COMPILADO
UNIDAD TEMÁTICA
PROGRAMACIÓN II

FUNDAMENTOS DE PROGRAMACIÓN ORIENTADA A


OBJETOS

PREPARADO POR
YOIS S. PASCUAS RENGIFO
Ingeniera de Sistemas
Magíster en Ciencias de la Información y las Comunicaciones
y.pascuas@udla.edu.co

Compilado Programación II                                                                                                                                                                                                                  1
TABLA DE CONTENIDO

INTRODUCCIÓN   4  
COMPETENCIAS   5  
SUB  EJES  PROBLÉMICOS   5  
1.   CONCEPTOS  DE  PROGRAMACIÓN  ORIENTADA  A  OBJETOS   6  
1.1  EL  MUNDO  REAL  COMO  UNA  COLECCIÓN  DE  OBJETOS   7  
1.2  CARACTERÍSTICAS  DE  LA  POO   8  
1.3  IMPORTANCIA  DE  LA  POO   9  
1.4  PRINCIPIOS  FUNDAMENTALES  DE  LA  POO   9  
1.4.1  OBJETOS   10  
1.4.2   CLASE   12  
1.4.3   RELACIÓN  ENTRE  CLASE  Y  OBJETO   14  
1.4.4  ATRIBUTO   14  
1.4.5   MÉTODO   15  
1.4.6  MENSAJE   16  
1.5  ORIENTACIÓN  A  OBJETOS   17  
1.5.1   ABSTRACCIÓN   17  
1.5.2   ENCAPSULACIÓN   19  
1.5.3  MODULARIDAD   20  
1.5.4  HERENCIA   20  
1.5.5  POLIMORFISMO   21  
1.6  LENGUAJES  DE  PROGRAMACIÓN  ORIENTADO  A  OBJETOS   23  
2.   CLASES  Y  OBJETOS   26  
2.1   OBJETOS   27  
2.2   INSTANCIACIÓN  DE  LAS  CLASES:  LOS  OBJETOS   27  
2.2.1  REFERENCIAS  A  OBJETO  E  INSTANCIAS   27  
2.3   IDENTIFICACIÓN  DE  OBJETOS   28  
2.4   CLASES   28  
2.4.1  ATRIBUTOS   30  
2.4.2  MÉTODOS   30  
2.4.3   CONSTRUCTORES  Y  DESTRUCTORES   31  
2.5   APLICACIÓN  PRÁCTICA   34  
3.   HERENCIA   41  
3.1  VENTAJAS  DE  LA  HERENCIA   42  
3.2   TIPOS  DE  HERENCIA   42  
3.2.3  HERENCIA  MÚLTIPLE   43  
3.3   VISIBILIDAD  PÚBLICA,  PRIVADA  Y  PROTEGIDA   44  
3.4   CLASES  ABSTRACTAS  E  INTERFACES   45  
3.4.1  INTERFACES   47  
3.5  APLICACIÓN  PRÁCTICA  CON  LA  HERENCIA   49  
4.  POLIMORFISMO   54  

2 Universidad de la Amazonia - Tecnología en Informática y Sistemas


4.1  SOBRECARGA   55  
4.2  SOBREESCRITURA   56  
4.3  ENLACE  DINÁMICO   57  
4.4  FUNCIONES  VIRTUALES  Y  FUNCIONES  ABSTRACTAS   62  
4.4.1  FUNCIONES  VIRTUALES   64  
4.4.2  FUNCIONES  VIRTUALES  PURAS  Y  CLASES  ABSTRACTAS   68  
4.5  APLICACIÓN  PRÁCTICA  CON  EL  POLIMORFISMO   72  
5.RELACIONES  EN  EL  MODELO  OO   74  
5.1  ASOCIACIÓN   74  
5.2  AGREGACIÓN   74  
5.3  COMPOSICIÓN   75  
5.4  APLICACIÓN  DE  LAS  RELACIONES   76  
6.  REFERENCIAS   82  

Compilado Programación II                                                                                                                                                                                                                  3
INTRODUCCIÓN

La programación orientada a objetos (POO) es una nueva forma


de pensar, una manera distinta de enfocar y descomponer los
problemas para desarrollar y proponer soluciones de
programación. Actualmente, es una de las formas más
populares de programar y viene teniendo gran acogida en el
desarrollo de proyectos de software desde los últimos años. Esta
acogida se debe a sus grandes capacidades y ventajas frente a
las antiguas formas de programar.

Teniendo en cuenta lo anterior, es indispensable que toda


persona que vaya a desarrollar aplicaciones orientadas a objetos
aprenda primero la fundamentación y después el lenguaje de
programación; ya que existen diferentes lenguajes que permiten
su implementación y contienen sintaxis particulares.

El siguiente documento es el compilado de la Unidad Temática


de Programación II del programa Tecnología en Informática y
Sistemas modalidad distancia de la Universidad de la Amazonia.
En este documento se describen los conceptos básicos de la
programación orientada a objetos desde un punto de vista
global, especificando en algunos casos el lenguaje de
implementación de los ejemplos en el lenguaje de programación
c++ y java.

4 Universidad de la Amazonia - Tecnología en Informática y Sistemas


COMPETENCIAS

− Aplica los conceptos de la programación orientada a


objetos en el desarrollo de soluciones algorítmicas.
− Diferencia los conceptos de clase y objeto y hace uso de los
mismos para la construcción de programas en un lenguaje
de programación.
− Reconoce la sintaxis del lenguaje de programación java y
los procesos para el desarrollo de aplicaciones en esta
plataforma.

SUB EJES PROBLÉMICOS

− ¿Cómo la programación orientada a objetos permite dar


solución a problemas del sector productivo?.
− ¿Porqué es importante definir la técnica de programación
de acuerdo a los requerimientos?.
− ¿Cuales son las ventajas del paradigma orientado a objetos
en el desarrollo de software?

Compilado Programación II                                                                                                                                                                                                                  5
1. CONCEPTOS DE PROGRAMACIÓN ORIENTADA A
OBJETOS

Tradicionalmente, la programación fue hecha en una manera


secuencial o lineal, es decir una serie de pasos consecutivos con
estructuras consecutivas y bifurcaciones. Los lenguajes basados
en esta forma de programación ofrecían ventajas al principio,
pero el problema ocurre cuando los sistemas se vuelven
complejos. Estos programas escritos al estilo “espaguetti” no
ofrecen flexibilidad y el mantener una gran cantidad de líneas
de código en sólo bloque se vuelve una tarea complicada.

Frente a esta dificultad aparecieron los lenguajes basados en la


programación estructurada. La idea principal de esta forma de
programación es separar las partes complejas del programa en
módulos o segmentos que sean ejecutados conforme se
requieran. De esta manera tenemos un diseño modular,
compuesto por módulos independientes que puedan
comunicarse entre sí. Poco a poco este estilo de programación
fue reemplazando al estilo “espaguetti” impuesto por la
programación lineal.

Entonces, la evolución que se fue dando en la programación se


orientaba siempre a ir descomponiendo más el programa. Este
tipo de descomposición conduce directamente a la
programación orientada a objetos.

Pues la creciente tendencia de crear programas cada vez más


grandes y complejos llevó a los desarrolladores a crear una
nueva forma de programar que les permita crear sistemas de
niveles empresariales y con reglas de negocios muy complejas.
Para estas necesidades ya no bastaba la programación
estructurada ni mucho menos la programación lineal. Es así
como aparece la programación orientada a objetos (POO). La
POO viene de la evolución de la programación estructurada;
básicamente la POO simplifica la programación con la nueva

6 Universidad de la Amazonia - Tecnología en Informática y Sistemas


filosofía y nuevos conceptos que tiene. (Programación Orientada
a Objetos )

La POO es un paradigma de programación que usa objetos y sus


interacciones para diseñar aplicaciones y programas; es una metodología
que basa la estructura de los programas en torno a los objetos. Los
lenguajes de POO ofrecen medios y herramientas para describir los objetos
manipulados por un programa. Más que describir cada objeto
individualmente, estos lenguajes proveen una construcción (Clase) que
describe a un conjunto de objetos que poseen las mismas propiedades.
(Programación, 2007)

Grady Booch, autor del método de diseño orientado a objetos, define la


programación orientada a objetos como “un método de implementación en
ele que los programas se organizan como colecciones cooperativas de
objetos, cada uno de los cuales representan una instancia de alguna clase,
y cuyas clases son todas miembros de una jerarquía de clases unidas
mediante relaciones de herencia”. (Aguilar, 1996)

1.1 EL MUNDO REAL COMO UNA COLECCIÓN DE OBJETOS

La POO (OOP según sus siglas en inglés) es un paradigma de


programación que usa objetos y sus interacciones, para diseñar
aplicaciones y programas informáticos. Su uso se popularizó a
principios de la década de los años 1990. En la actualidad,
existe variedad de lenguajes de programación que soportan la
orientación a objetos; las ventajas de la POO son las siguientes:

− Fomenta la reutilización y extensión del código.


− Relacionar el sistema al mundo real.
− Permite crear sistemas más complejos.
− Facilita la creación de programas visuales.
− Construcción de prototipos.
− Agiliza el desarrollo de software.
− Facilita el trabajo en equipo.
− Facilita el mantenimiento del software.
− Lo interesante de la POO es que proporciona conceptos y
herramientas con las cuales se modela y representa el mundo
real tan fielmente como sea posible.

Compilado Programación II                                                                                                                                                                                                                  7
− Los programas son fáciles de diseñar debido a que los objetos
reflejan elementos del mundo real.
− Las aplicaciones son más sencillas para los usuarios debido a
que los datos innecesarios están ocultos.
− Los objetos son unidades autocontenidas.
− La productividad se incrementa debido a que puede reutilizar
el código.
− Los sistemas son fáciles de mantener y se adaptan a las
cambiantes necesidades de negocios.
− Es más fácil crear nuevos tipos de objetos a partir de los ya
existentes.
− Simplifica los datos complejos.
− Reduce la complejidad de la transacción.
− Confiabilidad.
− Robustez.
− Capacidad de ampliación.
− Permite mostrar la magnitud de los lenguajes de
programacion basada en objetos.
− Crea sistemas mas flexibles, que en un futuro son
modificables.

1.2 CARACTERÍSTICAS DE LA POO

- Uniformidad
Ya que es la representación de los objetos implica tanto el
análisis como el diseño y la codificación de los mismos.

- Comprensión
Tanto los datos que componen los objetos, como los
procedimientos que los manipulan, están agrupados en
clases, que se corresponden con las estructuras de
información que el programa trata.

- Flexibilidad
Al tener relacionados los procedimientos que manipulan los
datos con los datos a tratar, cualquier cambio que se realice
sobre ellos quedará reflejado automáticamente en cualquier
lugar donde estos datos aparezcan.

8 Universidad de la Amazonia - Tecnología en Informática y Sistemas


- Estabilidad
Dado que permite un tratamiento diferenciado de aquellos
objetos que permanecen constantes en el tiempo sobre
aquellos que cambian con frecuencia permite aislar las
partes del programa que permanecen inalterables en el
tiempo. (POO)

1.3 IMPORTANCIA DE LA POO

Algunas de las causas que están influyendo considerablemente en el


notable desarrollo de las técnicas orientadas a objetos son:
- La OO es especialmente adecuada para realizar determinadas
aplicaciones, sobre todo realización de prototipos y simulación de
programas.
- Los mecanismos de encapsulación de POO soportan un algo grado
de reutilizacón de código, que se incrementa por su mecanismos de
herencia.
- En el entorno de las bases de datos, la OO se adjunta bien a los
modelos semánticos de datos ara solucionar las limitaciones de los
modelos tradicionales, incluído el modelo relacional.
- Aumento de los lenguajes de POO (LPOO).
- Interfaces de usuario gráficos (por íconos) y visuales. Los interfaces
de usuario de una aplicación manipulan la entrada y salida del
usuario. Por consiguiente, su función principal es la comunicción
con el usuario final. La entrada al sistema se puede controlar a
través de líneas de órdenes o alternativamente el usuario puede
interactura con el sistema, con construcciones de programación
visuales, tales como inconos de menús, windows, macintosh.

1.4 PRINCIPIOS FUNDAMENTALES DE LA POO

Los principios fundamentales en que se apoyan las tecnologías


orientadas a objetos son los objetos, clases, atributos, métodos
y mensajes, se representan en la siguiente figura:

Compilado Programación II                                                                                                                                                                                                                  9
Programación  
Orientada  a  Objetos    

Objeto   Clase   Método     Atributo  

Contenedor  de  tipo  de  datos  


asociados  a  un  objeto,  que  
Entidad  provista  de  un   Algoritmo  asociado  a  un  
conjunto  de  propiedades  o   Se  de`inen  las  propiedades  y   objeto,  cuya  ejecución  se   hace  los  datos  visibles  desde  
comportamiento  de  un  tipo   fuera  del  objeto  y  esto  se  
atributos  (datos)  y  métodos.   desencadena  tras  la  recepción  
Es  una  instancia  de  una  clase.     de  objeto  correcto.     de  un  "mensaje".     de`ine  como  sus  
características  
predeterminadas.    

1.4.1 OBJETOS

Es una entidad (tangible o intangible) que posee características


y acciones que realiza por sí solo o interactuando con otros
objetos. Un objeto es una entidad caracterizada por sus
atributos propios y cuyo comportamiento está determinado por
las acciones o funciones que pueden modificarlo, así como
también las acciones que requiere de otros objetos. Un objeto
tiene identidad e inteligencia y constituye una unidad que
oculta tanto datos como la descripción de su manipulación.
Puede ser definido como una encapsulación y una abstracción:
una encapsulación de atributos y servicios, y una abstracción
del mundo real.

Para el contexto del Enfoque Orientado a Objetos (EOO) un


objeto es una entidad que encapsula datos (atributos) y
acciones o funciones que los manejan (métodos). También para
el EOO un objeto se define como una instancia o
particularización de una clase.

Los objetos de interés durante el desarrollo de software no sólo


son tomados de la vida real (objetos visibles o tangibles),
también pueden ser abstractos. En general son entidades que
10 Universidad de la Amazonia - Tecnología en Informática y Sistemas
juegan un rol bien definido en el dominio del problema. Un
libro, una persona, un carro, un polígono, son apenas algunos
ejemplos de objeto.

Cada objeto puede ser considerado como un proveedor de


servicios utilizados por otros objetos que son sus clientes. Cada
objeto puede ser a al vez proveedor y cliente. De allí que un
programa pueda ser visto como un conjunto de relaciones entre
proveedores-clientes. Los servicios ofrecidos por los objetos son
de dos tipos:
1. Los datos, que llamamos atributos
2. Las acciones o funciones, que llamamos métodos.

Características Generales

- Un objeto se identifica por un nombre o un identificador único que lo


diferencia de los demás. Ejemplo: el objeto Cuenta de Ahorros número 12345
es diferente al objeto Cuenta de Ahorros número 25789. En este caso el
identificador que los hace únicos es el número de la cuenta.

- Un objeto posee estados. El estado de un objeto está determinado por los


valores que poseen sus atributos en un momento dado.

- Un objeto tiene un conjunto de métodos. El comportamiento general de los


objetos dentro de un sistema se describe o representa mediante sus
operaciones o métodos. Los métodos se utilizarán para obtener o cambiar el
estado de los objetos, así como para proporcionar un medio de comunicación
entre objetos.

- Un objeto tiene un conjunto de atributos. Los atributos de un objeto contienen


valores que determinan el estado del objeto durante su tiempo de vida. Se
implementan con variables, constantes y estructuras de datos (similares a los
campos de un registro).

- Los objetos soportan encapsulamiento. La estructura interna de un objeto


normalmente está oculta a los usuarios del mismo. Los datos del objeto están
disponibles solo para ser manipulados por los propios métodos del objeto. El
único mecanismo que lo conecta con el mundo exterior es el paso de
mensajes.

-  Un objeto tiene un tiempo de vida dentro del programa o sistema que lo crea
y utiliza. Para ser utilizado en un algoritmo el objeto debe ser creado con una
instrucción particular (New ó Nuevo) y al finalizar su utilización es destruido
con el uso de otra instrucción o de manera automática. (Programación, 2007)

Compilado Programación II                                                                                                                                                                                                                  11


Figura. Ejemplo de la clasificación de los objetos

Objeto  

Animal   Planta  

Mamímero   Flor   Clavel  

Perro   Humano  

Comerciant
Pluto   e   Artista  

1.4.2 CLASE

La clase es la unidad de modularidad en el EOO. La tendencia


natural del individuo es la de clasificar los objetos según sus
características comunes (clase). Por ejemplo, las personas que
asisten a la universidad se pueden clasificar (haciendo
abstracción) en estudiante, docente, empleado e investigador.
La clase puede definirse como la agrupación o colección de
objetos que comparten una estructura común y un
comportamiento común.

Es una plantilla que contiene la descripción general de una


colección de objetos. Consta de atributos y métodos que
resumen las características y el comportamiento comunes de un
conjunto de objetos. Todo objeto (también llamado instancia de
una clase), pertenece a alguna clase. Mientras un objeto es una
entidad concreta que existe en el tiempo y en el espacio, una
clase representa solo una abstracción.

Todos aquellos objetos que pertenecen a la misma clase son


descritos o comparten el mismo conjunto de atributos y
métodos. Todos los objetos de una clase tienen el mismo
formato y comportamiento, son diferentes únicamente en los

12 Universidad de la Amazonia - Tecnología en Informática y Sistemas


valores que contienen sus atributos. Todos ellos responden a los
mismos mensajes.

Su sintaxis algorítmica es:


Clase <Nombre de la Clase> ...
FClase <Nombre de la Clase>;

Características Generales

- Una clase es un nivel de abstracción alto. La clase permite


describir un conjunto de características comunes para los
objetos que representa. Ejemplo: La clase Avión se puede
utilizar para definir los atributos (tipo de avión, distancia,
altura, velocidad de crucero, capacidad, país de origen, etc.) y
los métodos (calcular posición en el vuelo, calcular velocidad
de vuelo, estimar tiempo de llegada, despegar, aterrizar,
volar, etc.) de los objetos particulares Avión que representa.

- Un objeto es una instancia de una clase. Cada objeto


concreto dentro de un sistema es miembro de una clase
específica y tiene el conjunto de atributos y métodos
especificados en la misma.

- Las clases se relacionan entre sí mediante una jerarquía.


Entre las clases se establecen diferentes tipos de relaciones
de herencia, en las cuales la clase hija (subclase) hereda los
atributos y métodos de la clase padre (superclase), además de
incorporar sus propios atributos y métodos.

Ejemplos: Superclase: Clase Avión


Subclases de Avión: Clase Avión Comercial, Avión de
Combate, Avión de Transporte

- Los nombres o identificadores de las clases deben colocarse


en singular (clase Animal, clase Carro, clase Alumno).

Compilado Programación II                                                                                                                                                                                                                  13


1.4.3 RELACIÓN ENTRE CLASE Y OBJETO
Algorítmicamente, las clases son descripciones netamente estáticas o plantillas
que describen objetos. Su rol es definir nuevos tipos conformados por atributos y
operaciones. Por el contrario, los objetos son instancias particulares de una clase.
Las clases son una especie de molde de fábrica, en base al cual son construidos
los objetos. Durante la ejecución de un programa sólo existen los objetos, no las
clases.

La declaración de una variable de una clase NO crea el objeto.


La asociación siguiente: <Nombre_Clase> <Nombre_Variable>; (por ejemplo,
Rectángulo R), no genera o no crea automáticamente un objeto Rectángulo. Sólo
indica que R será una referencia o una variable de objeto de la clase Rectángulo.
La creación de un objeto, debe ser indicada explícitamente por el programador, de
forma análoga a como inicializamos las variables con un valor dado, sólo que
para los objetos se hace a través de un método Constructor.

1.4.4 ATRIBUTO

Son los datos o variables que caracterizan al objeto y cuyos


valores en un momento dado indican su estado. Un atributo es
una característica de un objeto. Mediante los atributos se define
información oculta dentro de un objeto, la cual es manipulada
solamente por los métodos definidos sobre dicho objeto.

Un atributo consta de un nombre y un valor. Cada atributo está


asociado a un tipo de dato, que puede ser simple (entero, real,
lógico, carácter, string) o estructurado (arreglo, registro, archivo,
lista, etc.)

Su sintaxis algorítmica es:

<Modo de Acceso> <Tipo de dato> <Nombre del Atributo>;

Los modos de acceso son:

- Público: Atributos (o Métodos) que son accesibles fuera de la


clase. Pueden ser llamados por cualquier clase, aun si no
está relacionada con ella. Este modo de acceso también se
puede representar con el símbolo (+).

14 Universidad de la Amazonia - Tecnología en Informática y Sistemas


- Privado: Atributos (o Métodos) que sólo son accesibles dentro
de la implementación de la clase. También se puede
representar con el símbolo (–).

- Protegido: Atributos (o Métodos) que son accesibles para la


propia clase y sus clases hijas (subclases). También se puede
representar con el símbolo (#).

1.4.5 MÉTODO

Son las operaciones (acciones o funciones) que se aplican sobre


los objetos y que permiten crearlos, cambiar su estado o
consultar el valor de sus atributos. Los métodos constituyen la
secuencia de acciones que implementan las operaciones sobre
los objetos. La implementación de los métodos no es visible
fuera de objeto.

La sintaxis algorítmica de los métodos expresados como


funciones y acciones es: Para funciones se pueden usar
cualquiera de estas dos sintaxis:

<Modo de Acceso> Función <Nombre> [(Lista Parámetros)]:


<Descripción del Tipo de datos>

Para acciones:

<Modo de Acceso> Acción <Nombre> [(Lista Parámetros)] donde


los parámetros son opcionales.

Ejemplo: Un rectángulo es un objeto caracterizado por los


atributos Largo y Ancho, y por varios métodos, entre otros
Calcular su área y Calcular su perímetro.

Características Generales

- Cada método tiene un nombre, cero o más parámetros (por


valor o por referencia) que recibe o devuelve y un algoritmo
con el desarrollo del mismo.

Compilado Programación II                                                                                                                                                                                                                  15


- En particular se destaca el método constructor, que no es
más que el método que se ejecuta cuando el objeto es creado.
Este constructor suele tener el mismo nombre de la clase/
objeto, pero aunque es una práctica común, el método
constructor no necesariamente tiene que llamarse igual a la
clase (al menos, no en pseudos-código). Es un método que
recibe cero o más parámetros y lo usual es que inicialicen los
valores de los atributos del objeto.

- En lenguajes como Java y C++ se puede definir más de un


método constructor, que normalmente se diferencian entre sí
por la cantidad de parámetros que reciben.

- Los métodos se ejecutan o activan cuando el objeto recibe un


mensaje, enviado por un objeto o clase externo al que lo
contiene, o por el mismo objeto de manera local.
(Programación, 2007)

1.4.6 MENSAJE

Es la petición de un objeto a otro para solicitar la ejecución de


alguno de sus métodos o para obtener el valor de un atributo
público. Estructuralmente, un mensaje consta de 3 partes:

1. Identidad del receptor: Nombre del objeto que contiene el


método a ejecutar.
2. Nombre del método a ejecutar: Solo los métodos declarados
públicos.
3. Lista de Parámetros que recibe el método (cero o mas
parámetros)

Su sintaxis algorítmica es:


<Variable_Objeto>.<Nombre_Método> ( [<Lista de Parámetros> ]
);

Cuando el objeto receptor recibe el mensaje, comienza la


ejecución del algoritmo contenido dentro del método invocado,

16 Universidad de la Amazonia - Tecnología en Informática y Sistemas


recibiendo y/o devolviendo los valores de los parámetros
correspondientes, si los tiene ya que son opcionales: ( [ ] )

1.5 ORIENTACIÓN A OBJETOS

La orientación a objetos puede describirse como el conjunto de


disciplinas (ingeniería) que desarrollan y modelizan software
que facilitan la construcción de sistemas complejos a partir de
componentes. El atractivo intuito de la orientación a objetos es
que proporciona conceptos y herramientas con las cuales se
modela y representa el mundo real tan fielmente como sea
posible. Las ventajas de la orientación a objetos son muchas en
programación y modelación de datos.

La programación orientada a objetos permite una


representación más directa del modelo de mundo real en el código. El
resultado es que la transformación radical normal de los requisitos del sistema
(definido en términos de usuario) a la especificación del sistema (definido en
términos de computador) se reduce considerablemente. (Aguilar, 1996)

El Enfoque Orientado a Objeto se basa en cuatro principios que constituyen la


base de todo desarrollo orientado a objetos. Estos principios son: la Abstracción,
el Encapsulamiento, la Modularidad y la Herencia. Otros elementos a destacar en
el EOO son: Polimorfismo, Enlace dinámico (o binding), Concurrencia y
Persistencia.

Programación  Orientada  a  Objetos    

Abstracción   Encapsulamiento   Modularidad   Herencia  

1.5.1 ABSTRACCIÓN

La abstracción consiste en captar las características esenciales


de un objeto, así como su comportamiento. Por ejemplo, los
automóviles, ¿Qué características se pueden abstraer de los
automóviles? O lo que es lo mismo ¿Qué características

Compilado Programación II                                                                                                                                                                                                                  17


semejantes tienen todos los automóviles? Todos tendrán una
marca, un modelo, número de chasis, peso, llantas, puertas,
ventanas, etc. Y en cuanto a su comportamiento todos los
automóviles podrán acelerar, frenar, retroceder, etc. En los
lenguajes de programación orientada a objetos, el concepto de
Clase es la representación y el mecanismo por el cual se
gestionan las abstracciones.

Por ejemplo en Java se tiene:


public class Automovil {
// variables
// métodos }

Una abstracción denota las características esenciales de un


objeto (datos y operaciones), que lo distingue de otras clases de
objetos. Decidir el conjunto correcto de abstracciones de un
determinado dominio, es el problema central del diseño
orientado a objetos.

Los mecanismos de abstracción son usados en el enfoque OO


para extraer y definir del medio a modelar, sus características y
su comportamiento. Dentro del enfoque OO son muy usados
mecanismos de abstracción: la Generalización, la Agregación y
la clasificación.

−  La generalización es el mecanismo de abstracción mediante


el cual un conjunto de clases de objetos son agrupados en
una clase de nivel superior (Superclase), donde las
semejanzas de las clases constituyentes (Subclases) son
enfatizadas, y las diferencias entre ellas son ignoradas. En
consecuencia, a través de la generalización, la superclase
almacena datos generales de las subclases, y las subclases
almacenan sólo datos particulares. La especialización es lo
contrario de la generalización. La clase Médico es una
especialización de la clase Persona, y a su vez, la clase
Pediatra es una especialización de la superclase Médico.

−  La agregación es el mecanismo de abstracción por el cual


una clase de objeto es definida a partir de sus partes (otras

18 Universidad de la Amazonia - Tecnología en Informática y Sistemas


clases de objetos). Mediante agregación se puede definir por
ejemplo un computador, por descomponerse en: la CPU, la
ULA, la memoria y los dispositivos periféricos. El contrario de
agregación es la descomposición.

− La clasificación consiste en la definición de una clase a


partir de un conjunto de objetos que tienen un
comportamiento similar. La ejemplificación es lo contrario a
la clasificación, y corresponde a la instanciación de una
clase, usando el ejemplo de un objeto en particular.

1.5.2 ENCAPSULACIÓN

El encapsulamiento consiste en unir en la Clase las características y


comportamientos, esto es, las variables y métodos. Es tener todo esto es una sola
entidad. La utilidad del encapsulamiento va por la facilidad para manejar la
complejidad, ya que se tienen las Clases como cajas negras donde sólo se conoce
el comportamiento pero no los detalles internos, y esto es conveniente porque nos
interesará será conocer qué hace la Clase pero no será necesario saber cómo lo
hace.

La idea central del encapsulamiento es esconder los detalles y mostrar lo


relevante. Permite el ocultamiento de la información separando el aspecto
correspondiente a la especificación de la implementación; de esta forma,
distingue el "qué hacer" del "cómo hacer". La especificación es visible al usuario,
mientras que la implementación se le oculta.

El encapsulamiento en un sistema orientado a objeto se representa en cada clase


u objeto, definiendo sus atributos y métodos con los siguientes modos de acceso:

− Público (+) Atributos o Métodos que son accesibles fuera de la clase. Pueden
ser llamados por cualquier clase, aun si no está relacionada con ella.
− Privado (-) Atributos o Métodos que solo son accesibles dentro de la
implementación de la clase.
− Protegido (#): Atributos o Métodos que son accesibles para la propia clase y
sus clases hijas (subclases).

Los atributos y los métodos que son públicos constituyen la interfaz de la clase,
es decir, lo que el mundo exterior conoce de la misma.
Normalmente lo usual es que se oculten los atributos de la clase y solo sean
visibles los métodos, incluyendo entonces algunos de consulta para ver los
valores de los atributos. El método constructor (Nuevo, New) siempre es Público.

Compilado Programación II                                                                                                                                                                                                                  19


1.5.3 MODULARIDAD

Es la propiedad que permite tener independencia entre las diferentes partes de


un sistema. La modularidad consiste en dividir un programa en módulos o
partes, que pueden ser compilados separadamente, pero que tienen conexiones
con otros módulos. En un mismo módulo se suele colocar clases y objetos que
guarden una estrecha relación. El sentido de modularidad está muy relacionado
con el ocultamiento de información. La modularización, como indica
Liskov consiste en dividir un programa en módulos que se
puedan compilar por separado, pero que tienen conexiones con
otros módulos. La modularidad permite la descomposición en
un conjunto de módulos cohesivos y débilmente acoplados.

1.5.4 HERENCIA

Es el proceso mediante el cual un objeto de una clase adquiere


propiedades definidas en otra clase que lo preceda en una
jerarquía de clasificaciones. Permite la definición de un nuevo
objeto a partir de otros, agregando las diferencias entre ellos
(Programación Diferencial), evitando repetición de código y
permitiendo la reusabilidad. Las clases heredan los datos y
métodos de la superclase. Un método heredado puede ser
sustituido por uno propio si ambos tienen el mismo nombre.

La herencia puede ser simple (cada clase tiene sólo una


superclase) o múltiple (cada clase puede tener asociada varias
superclases). La clase Docente y la clase Estudiante heredan las
propiedades de la clase Persona (superclase, herencia simple).
La clase Preparador (subclase) hereda propiedades de la clase
Docente y de la clase Estudiante (herencia múltiple).

1.5.4.1 Principios de la jerarquía

El mundo está organizado de una manera jerárquica, en un orden. De esta


forma, las clases dentro de un programa también se presentan ordenadas
en jerarquías, formándose los árboles de herencia. Por ejemplo, viendo en
nuestro mundo, podemos tener como mascota un perro “siberiano”,
jerárquicamente éste estaría dentro del grupo de los canes o perros, a la
vez dentro de los mamíferos, dentro de los vertebrados, y así varios niveles

20 Universidad de la Amazonia - Tecnología en Informática y Sistemas


de jerarquía dentro de los cuales se encuentra. La jerarquía se encuentra
ligada a la “Herencia”.

La herencia es la propiedad que permite a los objetos construirse a partir de otros objetos.
La utilidad de la herencia es que las clases hijas reciben propiedades de sus clases padres,
evitando la necesidad de repetir el código anterior, haciendo el código reutilizable. Existen
varias formas de determinar qué atributos y comportamientos pueden heredar las clases
hijas de su superclase. El propio acto de tomar propiedades de su superclase se
denomina “herencia”.

Los objetos forman siempre una organización jerárquica, en el sentido de


que ciertos objetos son superiores a otros de cierto modo. Existen varios
tipos de jerarquías: simples, cuando su estructura pueda ser representada
por medio de un "árbol", es decir, tienen solo una clase superior, padre
superclase; complejas, cuando un hijo puede tener varios padres (es algo
más difícil de manejar y Java no permite estos casos) (Principios de la
POO).

1.5.5 POLIMORFISMO

Es una propiedad del EOO que permite que un método tenga múltiples
implementaciones, que se seleccionan en base al tipo objeto indicado al solicitar
la ejecución del método. El polimorfismo operacional o sobrecarga operacional
permite aplicar operaciones con igual nombre a diferentes clases o están
relacionados en términos de inclusión. En este tipo de polimorfismo, los métodos
son interpretados en el contexto del objeto particular, ya que los métodos con
nombres comunes son implementados de diferente manera dependiendo de cada
clase.

Por ejemplo, el área de un cuadrado, rectángulo y círculo, son calculados de


manera distinta; sin embargo, en sus clases respectivas puede existir la
implementación del área bajo el nombre común Área. En la práctica y
dependiendo del objeto que llame al método, se usará el código correspondiente.

Ejemplos:

Superclase: Clase Animal


Subclases: Clases Mamífero, Ave, Pez

Se puede definir un método Comer en cada subclase, cuya implementación


cambia de acuerdo a la clase invocada, sin embargo el nombre del método es el
mismo.

Mamifero.Comer ≠ Ave.Comer ≠ Pez.Comer

Compilado Programación II                                                                                                                                                                                                                  21


Otro ejemplo de polimorfismo es el operador +. Este operador tiene dos funciones
diferentes de acuerdo al tipo de dato de los operandos a los que se aplica. Si los
dos elementos son numéricos, el operador + significa suma algebraica de los
mismos, en cambio si por lo menos uno de los operandos es un String o Carácter,
el operador es la concatenación de cadenas de caracteres.

Otro ejemplo de sobrecarga es cuando tenemos un método definido originalmente


en la clase madre, que ha sido adaptado o modificado en la clase hija. Por
ejemplo, un método Comer para la clase Animal y otro Comer que ha sido
adaptado para la clase Ave, quien está heredando de la clase Animal.

Cuando se desea indicar que se está invocando (o llamando) a un método


sobrecargado y que pertenece a otra clase (por ejemplo, a la clase padre) lo
indicamos con la siguiente sintaxis:

Clase_Madre::nombre_método;

Para el ejemplo, la llamada en la clase hija Ave del método sobrecargado Comer
de la clase madre Animal sería:

Animal::Comer

Recomendado…

http://webdelprofesor.ula.ve/ingenieria/hyelitza/materias/prog
ramacion2/oxo/ProfaYusneyi_Tema8_POOClasesyObjetos.pdf

Figura. Resumen características OO

Abstracción   Encapsulamiento   Herencia   Polimor9ismo  

Cada  objeto  puede  


realizar  trabajo,   Reúne  a  todos  los  
informar  y   elementos  que   Los  objetos   Se  re`iere  a  
cambiar  su  estado   pueden   heredan  las   comportamientos  
y  comunicarse  con   considerarse   propiedades  y  el   diferentes,  
otros  objetos  en  el   pertenecientes  a   comportamiento   asociados  a  
sistema  sin   una  misma   de  todas  las  clases   objetos  distintos,  
revelar  cómo  se   entidad,  al  mismo   a  las  que   pueden  compartir  
implementan   nivel  de   pertenecen.     el  mismo  nombre.    
estas   abstracción.  
características.  

22 Universidad de la Amazonia - Tecnología en Informática y Sistemas


1.6 LENGUAJES DE PROGRAMACIÓN ORIENTADO A
OBJETOS

Se le llama así a cualquier lenguaje de programación que implemente los


conceptos definidos por la programación orientada a objetos. Cabe notar
que los conceptos definidos en la programación orientada a objetos no son
una condición sino que son para definir que un lenguaje es orientado a
objetos. Existen conceptos que pueden estar ausentes en un lenguaje dado
y sin embargo, no invalidar su definición como lenguaje orientado a
objetos. Quizás las condiciones mínimas necesarias las provee el
formalismo que modeliza mejor las propiedades de un sistema orientado a
objetos: los tipos de datos abstractos.

Siguiendo esa idea, cualquier lenguaje que permita la definición


de tipos de datos, de operaciones nuevas sobre esos tipos de
datos, y de instanciar el tipo de datos podría ser considerado
orientado a objetos.
Esta definición concuerda incluso con ciertos ejemplos
prácticos, que no son considerados dentro de la programación
orientada a objetos, pero que podrían serlo. Por ejemplo, la
programación de interfaces gráficas de usuario para los
sistemas X-Window utilizando infraestructuras de funciones y
APIs como Motif, Xview y Xlib, son realizadas usualmente en
lenguaje C, pero organizando el código en una manera que
"parecen objetos" (los Widgets). (Wikipedia)

Entre los lenguajes orientados a objetos se destacan los


siguientes:

− ABAP
− ABL Lenguaje de programación de OpenEdge de Progress
Software
− ActionScript
− ActionScript 3
− Ada
− C++
− C#
− Clarion
− Clipper (lenguaje de programación) (Versión 5.x con librería
de objetos Class(y))

Compilado Programación II                                                                                                                                                                                                                  23


− D
− Object Pascal (Delphi)
− Gambas
− Harbour
− Eiffel
− Java
− JavaScript (la herencia se realiza por medio de la
programación basada en prototipos)
− Lexico (en castellano)
− Objective-C
− Ocaml
− Oz
− R
− Perl (soporta herencia múltiple. La resolución se realiza en
preorden, pero puede modificarse al algoritmo linearization
C3 por medio del módulo Class::C3 en CPAN)
− PHP (a partir de su versión 5)
− PowerBuilder
− Python
− Ruby
− Smalltalk (Proyecto investigativo. Influenció a Java.)
− Magik (SmallWorld)
− Vala
− VB.NET
− Visual FoxPro (en su versión 6)
− Visual Basic 6.0
− Visual Objects
− XBase++
− Lenguaje DRP
− Lenguaje de programación Scala (lenguaje usado por Twitter)

Muchos de estos lenguajes de programación no son puramente


orientados a objetos, sino que son híbridos que combinan la
POO con otros paradigmas. Al igual que C++ otros lenguajes,
como OOCOBOL, OOLISP, OOPROLOG y Object REXX, han
sido creados añadiendo extensiones orientadas a objetos a un
lenguaje de programación clásico.

24 Universidad de la Amazonia - Tecnología en Informática y Sistemas


Un nuevo paso en la abstracción de paradigmas de
programación es la Programación Orientada a Aspectos (POA).
Aunque es todavía una metodología en estado de maduración,
cada vez atrae a más investigadores e incluso proyectos
comerciales en todo el mundo. (Programación Orientada a
Objetos )

Compilado Programación II                                                                                                                                                                                                                  25


2. CLASES Y OBJETOS

Los métodos orientados a objetos utilizados para diseñar


sistemas de software complejos recurren a bloques básicos de
construcción, clases y objetos. En primer lugar pensemos en un
programa que trata de gestionar datos sobre los vehículos de
transporte público de una ciudad, por ejemplo Bogotá.
(Conceptos de objetos y clases en Java)

Superclases   Clases   Objetos  

Vehículo   Taxi   BLV252  

Bus   FZP30B  

Tren   VCE751  

En este ejemplo se ha considerado que el problema consta de


tres tipos de vehículo: taxi, bús y tren, y que esos tipos los
denominamos clases. ¿Qué haría en Java para definir una
clase? Indicar sus propiedades y operaciones (métodos)
disponibles, por ejemplo:

/* Ejemplo Clase Taxi - aprenderaprogramar.com */


Clase Taxi {
Propiedades:
Matrícula identificativa
Distrito en el que opera
Tipo de motor diesel o gasolina

26 Universidad de la Amazonia - Tecnología en Informática y Sistemas


Coordenadas en las que se ubica
Operaciones disponibles:
Asignar una matrícula
Asignar un distrito
Asignar un tipo de motor
Ubicar en unas coordenadas
}

Los objetos y las clases se comparan con las variables y tipos en lenguaje
de programación convencional. Una variable es una instancia de un tipo,
como un objeto es una instancia de una clase. Sin embargo. Una clase es
más expresiva que un tipo. Una clase describe un grupo similar de objetos
y encapsula el estado de un objeto: las estructura de datos y las funciones
que manipulan esas estructuras. (Aguilar, 1996)

2.1 OBJETOS

Una definición típica de un objeto es aquella que lo considera como una


cosa tangible, algo que se puede reconocer visual o conceptualmente.
Muchos objetos tienen límites físicos distintos, tales como una silla o una
mesa.

2.2 INSTANCIACIÓN DE LAS CLASES: LOS OBJETOS

2.2.1 REFERENCIAS A OBJETO E INSTANCIAS

Los tipos simples de Java describían el tamaño y los valores de


las variables. Cada vez que se crea una clase se añade otro tipo
de dato que se puede utilizar igual que uno de los tipos simples.
Por ello al declarar una nueva variable, se puede utilizar un
nombre de clase como tipo. A estas variables se las conoce como
referencias a objeto.

Todas las referencias a objeto son compatibles también con las


instancias de subclases de su tipo. Del mismo modo que es
correcto asignar un byte a una variable declarada como int, se
puede declarar que una variable es del tipo MiClase y guardar
una referencia a una instancia de este tipo de clase:

MiPunto p;
Compilado Programación II                                                                                                                                                                                                                  27
Esta es una declaración de una variable p que es una referencia
a un objeto de la clase MiPunto, de momento con un valor por
defecto de null. La referencia null es una referencia a un objeto
de la clase Object, y se podrá convertir a una referencia a
cualquier otro objeto porque todos los objetos son hijos de la
clase Object.

2.3 IDENTIFICACIÓN DE OBJETOS

Los criterios para identificar (buscar o localizar objetos son diferentes


según las metodología a utilizar. Yourdon considera tres etapas en la
identificación de los objetos: la perspectiva de los datos, la perspectiva
funcional y la perspectiva del comportamiento. Desde el punto de vista
funcional, el analista debe centrarse en los nombre: los nombres son
normalmente buenos indicadores de la existencia de un objeto en el
modelo (la definición de problema). La identificación de la responsabilidad
de un objeto es otro medio de solicitar cuál es la función a realizar; el
descubrimiento de objetos atendiendo a las responsabilidades nos conduce
a centrarnos en verbos en la frase de definición de un problema, en lugar
de en los nombres.

Otra perspectiva a considerar en la búsqueda de objetos es el


comportamiento. En este caso, la pregunta clave es: ¿Cómo se comunican
los objetos entre sí?¿Con quienes se comunican?¿cómo responden a los
mensajes, señales, interrupciones o cualquier otra forma de
comunicación?. Las posibles cosas candidatas a objetos son:

1. Cosas tangibles (avión, reactor nuclear, tren, libro, mesa)


2. Roles (doctor, paciente, empleado, cliente, taxista, propietario)
3. Incidentes (vuelo, accidente, suceso, llamada a un servicio)
4. Interacciones (compra, matrimonio, ventas)
5. Especificaciones (aparato de televisión: potencia, modelo, precio)
6. Dispositivos finos
7. Unidades organizacionales (departamentos, divisiones, etc)
8. Posiciones y lugares físicos o geográficos, significativos al sistema
9. Buscar sucesos (eventos) que deben ser grabados y recordados por el
sistema

2.4 CLASES

El elemento básico de la programación orientada a objetos en


Java es la clase. Una clase define la forma y comportamiento de
un objeto. Para crear una clase sólo se necesita un archivo
28 Universidad de la Amazonia - Tecnología en Informática y Sistemas
fuente que contenga la palabra clave reservada class seguida de
un identificador legal y un bloque delimitado por dos llaves para
el cuerpo de la clase.

class MiPunto {
}

Un archivo de Java debe tener el mismo nombre que la clase


que contiene, y se les suele asignar la extensión ".java". Por
ejemplo la clase MiPunto se guardaría en un fichero que se
llamase MiPunto.java. Hay que tener presente que en Java se
diferencia entre mayúsculas y minúsculas; el nombre de la
clase y el de archivo fuente han de ser exactamente iguales.

Aunque la clase MiPunto es sintácticamente correcta, es lo que


se viene a llamar una clase vacía, es decir, una clase que no
hace nada. Las clases típicas de Java incluirán variables y
métodos de instancia. Los programas en Java completos
constan por lo general de varias clases de Java en distintos
archivos fuente.

Una clase es una plantilla para un objeto. Por lo tanto define la


estructura de un objeto y su interfaz funcional, en forma de
métodos. Cuando se ejecuta un programa en Java, el sistema
utiliza definiciones de clase para crear instancias de las clases,
que son los objetos reales. Los términos instancia y objeto se
utilizan de manera indistinta. La forma general de una
definición de clase es:

class Nombre_De_Clase {
tipo_de_variable nombre_de_atributo1;
tipo_de_variable nombre_de_atributo2;
// . . .
tipo_devuelto nombre_de_método1( lista_de_parámetros ) {
cuerpo_del_método1;
}
tipo_devuelto nombre_de_método2( lista_de_parámetros ) {
cuerpo_del_método2;
}

Compilado Programación II                                                                                                                                                                                                                  29


// . . .
}

Los tipos tipo_de_variable y tipo_devuelto, han de ser tipos


simples Java o nombres de otras clases ya definidas. Tanto
Nombre_De_Clase, como los nombre_de_atributo y
nombre_de_método, han de ser identificadores Java válidos.

2.4.1 ATRIBUTOS

Los datos se encapsulan dentro de una clase declarando


variables dentro de las llaves de apertura y cierre de la
declaración de la clase, variables que se conocen como
atributos. Se declaran igual que las variables locales de un
método en concreto. Por ejemplo, este es un programa que
declara una clase MiPunto, con dos atributos enteros llamados
x e y.

class MiPunto {
int x, y; }

Los atributos se pueden declarar con dos clases de tipos: un


tipo simple Java, o el nombre de una clase). Cuando se realiza
una instancia de una clase (creación de un objeto) se reservará
en la memoria un espacio para un conjunto de datos como el
que definen los atributos de una clase. A este conjunto de
variables se le denomina variables de instancia.

2.4.2 MÉTODOS

Los métodos son subrutinas que definen la interfaz de una


clase, sus capacidades y comportamiento. Un método ha de
tener por nombre cualquier identificador legal distinto de los ya
utilizados por los nombres de la clase en que está definido. Los
métodos se declaran al mismo nivel que las variables de
instancia dentro de una definición de clase.

30 Universidad de la Amazonia - Tecnología en Informática y Sistemas


En la declaración de los métodos se define el tipo de valor que
devuelven y a una lista formal de parámetros de entrada, de
sintaxis tipo identificador separadas por comas. La forma
general de una declaración de método es:

tipo_devuelto nombre_de_método( lista-formal-de-parámetros ) {


cuerpo_del_método;
}

Por ejemplo el siguiente método devuelve la suma de dos


enteros:

int metodoSuma( int paramX, int paramY ) {


return ( paramX + paramY );
}

En el caso de que no se desee devolver ningún valor se deberá


indicar como tipo la palabra reservada void. Así mismo, si no se
desean parámetros, la declaración del método debería incluir un
par de paréntesis vacíos (sin void):

void metodoVacio( ) { };

Los métodos son llamados indicando una instancia individual


de la clase, que tendrá su propio conjunto único de variables de
instancia, por lo que los métodos se pueden referir directamente
a ellas. El método inicia() para establecer valores a las dos
variables de instancia sería el siguiente:

void inicia( int paramX, int paramY ) {


x = paramX;
y = paramY;
}

2.4.3 CONSTRUCTORES Y DESTRUCTORES

2.4.3.1 Constructores

Compilado Programación II                                                                                                                                                                                                                  31


Las clases pueden implementar un método especial llamado
constructor. Un constructor es un método que inicia un objeto
inmediatamente después de su creación. De esta forma se evita
el tener que iniciar las variables explícitamente para su
iniciación. El constructor tiene exactamente el mismo nombre
de la clase que lo implementa; no puede haber ningún otro
método que comparta su nombre con el de su clase. Una vez
definido, se llamará automáticamente al constructor al crear un
objeto de esa clase (al utilizar el operador new).

El constructor no devuelve ningún tipo, ni siquiera void. Su


misión es iniciar todo estado interno de un objeto (sus
atributos), haciendo que el objeto sea utilizable
inmediatamente; reservando memoria para sus atributos,
iniciando sus valores...

Por ejemplo:

MiPunto( ) {
inicia( -1, -1 );
}

Este constructor denominado constructor por defecto, por no


tener parámetros, establece el valor -1 a las variables de
instancia x e y de los objetos que construya. El compilador, por
defecto, llamará al constructor de la superclase Object() si no se
especifican parámetros en el constructor.

Este otro constructor, sin embargo, recibe dos parámetros:

MiPunto( int paraX, int paraY ) {


inicia( paramX, paramY );
}

La lista de parámetros especificada después del nombre de una


clase en una sentencia new se utiliza para pasar parámetros al
constructor. Se llama al método constructor justo después de
crear la instancia y antes de que new devuelva el control al

32 Universidad de la Amazonia - Tecnología en Informática y Sistemas


punto de la llamada. Así, cuando ejecutamos el siguiente
programa:

MiPunto p1 = new MiPunto(10, 20);


System.out.println( "p1.- x = " + p1.x + " y = " + p1.y );

Se muestra en la pantalla:

p1.- x = 10 y = 20

Para crear un programa Java que contenga ese código, se debe


de crear una clase que contenga un método main(). El intérprete
java se ejecutará el método main de la clase que se le indique
como parámetro.

2.4.3.2 Destrucción de los objetos

Cuando un objeto no va a ser utilizado, el espacio de memoria


dinámica que utiliza ha de ser liberado, así como los recursos
que poseía, permitiendo al programa disponer de todos los
recursos posibles. A esta acción se la da el nombre de
destrucción del objeto. En Java la destrucción se puede realizar
de forma automática o de forma personalizada, en función de
las características del objeto.

- La destrucción por defecto: Recogida de basura

El intérprete de Java posee un sistema de recogida de basura,


que por lo general permite que no nos preocupemos de liberar la
memoria asignada explícitamente.

El recolector de basura será el encargado de liberar una zona de


memoria dinámica que había sido reservada mediante el
operador new, cuando el objeto ya no va a ser utilizado más
durante el programa (por ejemplo, sale del ámbito de utilización,
o no es referenciado nuevamente). El sistema de recogida de
basura se ejecuta periódicamente, buscando objetos que ya no
estén referenciados.

Compilado Programación II                                                                                                                                                                                                                  33


- La destrucción personalizada: finalize

A veces una clase mantiene un recurso que no es de Java como


un descriptor de archivo o un tipo de letra del sistema de
ventanas. En este caso sería acertado el utilizar la finalización
explícita, para asegurar que dicho recurso se libera. Esto se
hace mediante la destrucción personalizada, un sistema similar
a los destructores de C++.

Para especificar una destrucción personalizada se añade un


método a la clase con el nombre finalize:

class ClaseFinalizada{
ClaseFinalizada() { // Constructor
// Reserva del recurso no Java o recurso compartido
}

protected void finalize() {


// Liberación del recurso no Java o recurso compartido
}
}

El intérprete de Java llama al método finalize(), si existe cuando


vaya a reclamar el espacio de ese objeto, mediante la recogida
de basura. Debe observarse que el método finalize() es de tipo
protected void y por lo tanto deberá de sobreescribirse con este
mismo tipo.

2.5 APLICACIÓN
PRÁCTICA

Por ejemplo en un campo, este


a su vez tendrá un número
determinado de olivos con sus
atributos (edad, número de
olivas, etc.). El campo tendrá
una función que será generar

34 Universidad de la Amazonia - Tecnología en Informática y Sistemas


una serie de beneficios por la producción.

− La clase que agrupará los atributos y funciones se llamará


Campo:
class Campo

− Las variables que guardarán los atributos propios de cada


objeto, también llamadas variables de instancia o miembros
dato serán:
int numeroOlivas; int edadOlivo;

− Los objetos de la clase Campo serán cada uno de los olivos


que pasarán el valor de los atributos para ser guardados en
las variables a través de un constructor:
Campo olivo1=new Campo(10,30) // 10 y 30 son los valores
de los atributos del olivo1 Campo olivo2=new Campo(15,35)
// 15 y 35 son los valores de los atributos del olivo2 .......etc

− Los Constructores de la clase recibirán el valor del atributo


para asignarlo a las variables de instancia de la clase:
Campo(edad,numOlivas){ // recibe los valores de los objetos
this.edadOlivo=edad; // los valores son asignados a las
variabl es de instancia.
this.numeroOlivas=numOlivas; }

− Los métodos o funciones se podrá llamar desde el objeto.


olivo1.beneficios(); // llamada a una función que retornará
un resultado.

Clase
Para crear una clase se utiliza la palabra reservada class y a
continuación el nombre de la clase. La definición de la clase se
pone entre las llaves de apertura y cierre. El nombre de la clase
empieza por letra mayúscula.

class Campo{
//miembros dato
}
//constructores //funciones miembro
Compilado Programación II                                                                                                                                                                                                                  35
Miembro dato
Los valores de los atributos se guardan en los miembros dato o
variables de instancia. Los nombres de dichas variables
comienzan por letra minúscula.

La clase denominada Campo, describe las características


comunes a los olivos(objetos):
− La edad del olivo.
− El número de olivas del olivo.
class Campo{
int numeroOlivas; // variable de instancia o miembro dato
int edadOlivo; // variable de instancia o miembro dato
// constructores
// métodos o funciones miembro }

Constructor
Un objeto de una clase se crea llamando a una función especial
denominada constructor de la clase. El constructor se llama de
forma automática cuando se crea un objeto, para situarlo en
memoria e inicializar los miembros dato declarados en la clase.
El constructor tiene el mismo nombre que la clase. Lo específico
del constructor es que no retorna ningún valor.
class Campo{
int numeroOlivas; // variable de instancia o miembro dato
int edadOlivo; // variable de instancia o miembro dato
Campo(edad,numOlivas){ // recibe los valores de los objetos
this.edadOlivo=edad; // los valores son asignados a las variables
de instancia.
this.numeroOlivas=numOlivas; }
}

El constructor recibe dos valores que guardan los parámetros


(edad, numOlivas) y con ellos inicializa los miembros dato
edadOlivo y numeroOlivas. Una clase puede tener más de un
constructor. Por ejemplo, el segundo constructor crea un olivo
cuya edad es siempre 30.

36 Universidad de la Amazonia - Tecnología en Informática y Sistemas


class Campo{
int numeroOlivas; // variable de instancia o miembro dato
int edadOlivo; // variable de instancia o miembro dato
Campo(edad,numOlivas){ // recibe los valores de los objetos
this.edadOlivo=edad; // los valores son asignados a las variables
de instancia.
this.numeroOlivas=numOlivas; }
Campo(numOlivas){ // recibe los valores de los objetos
this.edadOlivo= 30; // los valores son asignados a las variables
de instancia.
this.numeroOlivas=numOlivas; }
}

Método
En el lenguaje Java las funciones miembro o métodos se definen
en la clase y se llaman mediante los objetos. El nombre de las
funciones miembro o métodos comie nza por letra minúscula.
La definición de una función tiene el siguiente formato:

tipo nombreFuncion(tipo parm1, tipo parm2, tipo parm3){


//...sentencias }

Entre las llaves de apertura y cierre se coloca la definición de la


función. tipo indica el tipo de dato que puede ser int, double,
etc. Para llamar a una función miembro o método se escribe
objeto.nombreFuncion(arg1, arg2, arg3); o tambien:
retorno=objeto.nombreFuncion(arg1, arg2, arg3);

Cuando se llama a la función, los argumentos arg1, arg2, arg3


se copian en los parámetros parm1, parm2, parm3 y se
ejecutan las sentencias dentro de la función. La función al
finalizar el valor resultante es devuelto mediante la sentencia
return y este valor resultante de retorno se puede asignar a una
variable. Cuando una función no devuelve nada se dice de tipo
void.

Cualquier variable declarada dentro de la función tiene una vida


temporal, existiendo en memoria, mientras la función esté
activa. Se trata de variables locales a la función. Por ejemplo:

Compilado Programación II                                                                                                                                                                                                                  37


void nombreFuncion(int parm){ //...
int i=5;
//... }

class Campo{
int numeroOlivas; // variable de instancia o miembro dato int
edadOlivo; // variable de instancia o miembro dato static final
double PVPOLIVA=0.05; // variable de clase
Campo(edad,numOlivas){ // primer constructor recibe los valores
de los objetos this.edadOlivo=edad; // los valores son asignados
a las variables de instancia.
this.numeroOlivas=numOlivas; }
Campo(numOlivas){ // segundo constructor recibe los valores de
los objetos this.edadOlivo= 30; // los valores son asignados a las
variables de instancia.
this.numeroOlivas=numOlivas; }
double beneficio(){ // función calculo beneficio
dinero=numeroOlivas*PVPOLIVA ;
return dinero; }
void sumaEdad (int incremento){ // función incremento edad del
olivo no devuelve nada
edadOlivo+=incremento ; }
void sumaOlivas (int sumaOlivas){ // función incremento de
olivas no devuelve nada
}
numeroOlivas+=sumaOlivas; }

− La función beneficio devuelve el total de multiplicar el valor de una oliva por el


número de olivas. Devuelve un dato de tipo decimal (double)
− La función sumaEdad incrementa la edad del olivo en caso que tengamos que
incrementarla. Esta función no devuelve nada por eso es de tipo void.
− La función sumaOlivas incrementa el número de olivas y también es de tipo
void.

Objeto

Para crear un objeto de una clase se usa la palabra reservada


new. Por ejemplo, Campo olivo1=new Campo(10, 30);

38 Universidad de la Amazonia - Tecnología en Informática y Sistemas


new reserva espacio en memoria para los miembros dato y
devuelve una referencia que se guarda en la variable olivo1 del
tipo Campo que denominamos ahora objeto.

El objeto denominado olivo1 de la clase Campo llama al primer


constructor en el listado. El olivo tendrá una edad de edad=10 y
un número de olivas numOlivas=30.

Campo olivo2=new Campo(40);


Crea un objeto denominado oliva2 de la clase Campo llamando
al segundo constructor, dicho olivo tendrá un numero de olivas
numOlivas=40 y su edad ya la asigna automáticamente el
constructor edadOlivo=30.

Acceso a miembros dato o funciones miembro

Desde un objeto se puede acceder a los miembros dato o


variables de instancia mediante la siguiente sintaxis
objeto.miembro;

Por ejemplo, podemos acceder al miembro dato edadOlivo, para


cambiar la edad de un objeto olivo. olivo1.edadOlivo=20;

El olivo1 que tenía inicialmente una edad de 10, mediante esta


sentencia se la cambiamos a 20.

Desde un objeto llamamos a las funciones miembro para


realizar una determinada tarea. Por ejemplo, desde olivo1
llamamos a la función beneficio para obtener la cantidad de
dinero del total de olivas del olivo1.
olivo1.beneficio();

La función miembro beneficio devuelve un decimal(double), que


guardaremos en una variable decimal beneficios1, para luego
usar este dato. double beneficios1=olivo1.beneficio();

System.out.println("El beneficio del primer olivo es: "+beneficios1);

Para incrementar la edad de un olivo olivo2, en 40 años.


Olivo2.sumaEdad(40);

Compilado Programación II                                                                                                                                                                                                                  39


Para incrementar el numero de olivas de un olivo olivo2, en 20
olivas. Olivo2.sumaOlivas(20);

Veamos la aplicación como quedaría. Para la aplicación creamos


otra clase llamada CampoAplicación. (Introducción a la POO)

public class CampoAplicación {


public static void main(String[] args) { // función principal
Campo olivo1=new Campo(10, 30); // objeto Campo olivo2=new
Campo(40); // objeto
System.out.println("La edad del olivo1 es: "+olivo1.edadOlivo);
olivo1.edadOlivo=20; //cambio de edad del olivo1
System.out.println("La nueva edad del olivo1 es:
"+olivo1.edadOlivo);
double beneficios1=olivo1.beneficio();
System.out.println("El beneficio del primer olivo es: "+beneficios1);
double beneficios2=olivo2.beneficio();
System.out.println("El beneficio del segundo olivo es:
"+beneficios2 );
System.out.println("La edad del olivo2 es: "+olivo2.edadOlivo);
olivo2.sumaEdad(40); // incremento de la edad mediante funcion
System.out.println("La nueva edad del olivo2 es:
"+olivo2.edadOlivo);
System.out.println("El número de olivas del olivo2 es:
"+olivo2.numeroOlivas); olivo2.sumaOlivas(20); // incremento el
numero de olivas
System.out.println("El nuevo número de olivas del olivo2 es:
"+olivo2.numeroOlivas);
}}

40 Universidad de la Amazonia - Tecnología en Informática y Sistemas


3. HERENCIA

En orientación a objetos la herencia es, después de la


agregación o composición, el mecanismo más utilizado para
alcanzar algunos de los objetivos más preciados en el desarrollo
de software como lo son la reutilización y la extensibilidad. A
través de ella los diseñadores pueden crear nuevas clases
partiendo de una clase o de una jerarquía de clases preexistente
(ya comprobadas y verificadas) evitando con ello el rediseño, la
modificación y verificación de la parte ya implementada. La
herencia facilita la creación de objetos a partir de otros ya
existentes e implica que una subclase obtiene todo el
comportamiento (métodos) y eventualmente los atributos
(variables) de su superclase.

Figura. Ejemplo conceptual de la herencia

Animal  

Herbívoro   Carnívoro  

Conejo   León   Hiena  

Omnívoro  

Humano  

Es la relación entre una clase general y otra clase más


específica. Por ejemplo: Si declaramos una clase párrafo
derivada de una clase texto, todos los métodos y variables
asociadas con la clase texto, son automáticamente heredados
por la subclase párrafo.

La herencia es uno de los mecanismos de los lenguajes de


programación orientada a objetos basados en clases, por medio

Compilado Programación II                                                                                                                                                                                                                  41


del cual una clase se deriva de otra de manera que extiende su
funcionalidad. La clase de la que se hereda se suele denominar
clase base, clase padre, superclase, clase ancestro (el
vocabulario que se utiliza suele depender en gran medida del
lenguaje de programación).

En los lenguajes que cuentan con un sistema de tipos fuerte y


estrictamente restrictivo con el tipo de datos de las variables, la
herencia suele ser un requisito fundamental para poder emplear
el Polimorfismo, al igual que un mecanismo que permita decidir
en tiempo de ejecución qué método debe invocarse en respuesta
a la recepción de un mensaje, conocido como enlace tardío (late
binding) o enlace dinámico (dynamic binding). (Wikipedia)

3.1 VENTAJAS DE LA HERENCIA

ü Se ahorra código
ü Permite reutilizar código extendiendo su funcionalidad
ü Desventajas
ü Se ahorra código
ü Se introduce una fuerte dependencia en la clase hija respecto
a la clase padre
ü Puede dificultar la reutilización
ü Un cambio en la clase padre puede tener efectos imprevistos
en las clases hijas
ü Un objeto de una clase hija puede tener un comportamiento
inconsistente con lo esperado de un objeto de la clase padre
ü Se establece una jerarquía o clasificación. Si cambia el
criterio de clasificación puede acarrear muchas
modificaciones (Herencia)

3.2 TIPOS DE HERENCIA

Mediante la herencia, las propiedades definidas en una clase


base son heredadas por la clase derivada. Se conoce esta
técnica por derivación. La nueva clase que se crea se denomina
clase derivada, la clase derivada puede añadir propiedades
específicas (atributos, métodos o roles) (Aguilar, 1996).
42 Universidad de la Amazonia - Tecnología en Informática y Sistemas
Hay dos tipos de herencia: Herencia Simple y Herencia Múltiple.
La primera indica que se pueden definir nuevas clases
solamente a partir de una clase inicial mientras que la segunda
indica que se pueden definir nuevas clases a partir de dos o
más clases iniciales. Java sólo permite herencia simple. Se dice
que la herencia es simple cuando una clase "hereda" de una
clase única, y que es múltiple cuando una clase hereda de
varias (más de una) clases.

3.2.1 HERENCIA SIMPLE

La herencia simple consiste en que una clase hereda


únicamente de otra. La relación de herencia hace posible
utilizar, desde la instancia, los atributos de la clase padre.
(Herencia simple y múltiple en Python)

Figura. Esquema conceptual de la herencia simple

A  

B   C  

D  

E  

3.2.3 HERENCIA MÚLTIPLE

Hace referencia a la característica en la que una clase puede heredar


comportamientos y características de más de una superclase. Esto
contrasta con la herencia simple, donde una clase sólo puede
heredar de una superclase.

Compilado Programación II                                                                                                                                                                                                                  43


Figura. Esquema conceptual de la herencia múltiple

A   B  

C  
La herencia múltiple permite a una clase tomar funcionalidades
de otras clases, como permitir a una clase llamada
MusicoEstudiante heredar de una clase llamada Persona, una
clase llamada Músico, y una clase llamada Trabajador. Esto
puede ser abreviado como MusicoEstudiante : Persona, Músico,
Trabajador.

Lenguajes que soportan herencia múltiple en su mayor parte


son: C++, Centura SQL Windows, CLOS, Eiffel, Object REXX,
Perl y Python.

3.3 VISIBILIDAD PÚBLICA, PRIVADA Y PROTEGIDA

Relacionado con el control de acceso a los miembros de la clase:


el concepto de clase incluye la idea de ocultación de datos, que,
básicamente, consiste en que no se puedan acceder a los datos
miembro directamente, sino que hay que hacerlo a través de las
funciones miembro públicas de la clase. Para controlar el acceso
a los miembros (datos y funciones) de una clase, se provee de 3
especificadores:

− public: un miembro declarado público es accesible en


cualquier parte del programa donde el objeto de la clase en
cuestión es accesible.
− private: un miembro declarado privado puede ser accedido
solamente por las funciones miembro de su propia clase o
por funciones amigas (friend) de su clase. En cambio no
44 Universidad de la Amazonia - Tecnología en Informática y Sistemas
puede ser accedido por funciones globales o por las funciones
propias de una clase derivada (herencia).
− protected: un miembro declarado protegido se comporta
exactamente igual que uno privado para las funciones
globales, pero actúa como un miembro público para las
funciones miembro de una clase derivada.

El siguiente programa de ejemplo (CLASES EN C++), se compone de tres


partes: la primera una declaración de una clase llamada Empleado:

class Empleado {
private:
char* m_nombre;
char* m_departamento;
char* m_posicion;
long m_salario;

public:
void ImprimirInfo();
void SetNombre( char* nombre ) { m_nombre = nombre }
void SetDepartamento( char * departamento) {
m_departamento = departamento }
void SetPosicion ( char* posicion ) { m_posicion = posicion
}
void SetSalario ( long salario ) { m_salario = salario }
const char* GetNombre( ){ return m_nombre }
const char* GetDepartamento( ){ return m_departamento }
const char* GetPosicion( ){ return m_posicion }
const char* GetSalario( ){ return m_salario }
};

3.4 CLASES ABSTRACTAS E INTERFACES

Una clase abstracta es una clase que no se puede instanciar se


usa únicamente para definir subclases. En cuanto uno de sus
métodos no tiene implementación (en Java, el método abstracto
se etiqueta con la palabra reservada abstract). Se utilizan las
clases abstractas cuando se desea definir una abstracción que

Compilado Programación II                                                                                                                                                                                                                  45


englobe objetos de distintos tipos y se quiere hacer uso del
polimorfismo.

Figura es una clase abstracta (nombre en cursiva en UML) porque


no tiene sentido calcular su área, pero sí la de un cuadrado o un
círculo. Si una subclase de Figura no redefine area(), deberá
declararse también como clase abstracta.

public abstract class Figura


{
protected double x;
protected double y;
public Figura (double x, double y)
{
this.x = x;
this.y = y;
}
public abstract double area ();
}

public class Circulo extends Figura


{
private double radio;
public Circulo (double x, double y, double radio)
{
46 Universidad de la Amazonia - Tecnología en Informática y Sistemas
super(x,y);
this.radio = radio;
}
public double area ()
{
return Math.PI*radio*radio;
}
}

public class Cuadrado extends Figura


{
private double lado;
public Cuadrado (double x, double y, double lado)
{
super(x,y);
this.lado = lado;
}
public double area ()
{
return lado*lado;
}
}

3.4.1 INTERFACES

Una interfaz es una clase


completamente abstracta (una
clase sin implementación). En el
ejemplo anterior, si no estuviera
interesada en conocer la posición
de una Figura, podríamos
eliminar por completo su
implementación y convertir
Figura en una interfaz:

Compilado Programación II                                                                                                                                                                                                                  47


public interface Figura
{
public double area ();
}

En Java, las interfaces se declaran con la palabra reservada


interface de manera similar a como se declaran las clases
abstractas.
− En la declaración de una interfaz, lo único que puede
aparecer son declaraciones de métodos (su nombre y
signatura, sin su implementación) y definiciones de
constantes simbólicas.

− Una interfaz no encapsula datos, sólo define cuáles son los


métodos que han de implementar los objetos de aquellas
clases que implementen la interfaz.

public class Circulo implements Figura


{
private double radio;

public Circulo (double radio)


{
this.radio = radio;
}

public double area ()


{
return Math.PI*radio*radio;
}
}

public class Cuadrado implements Figura


{
private double lado;

public Cuadrado (double lado)


{

48 Universidad de la Amazonia - Tecnología en Informática y Sistemas


this.lado = lado;
}

public double area ()


{
return lado*lado;
}
}

En Java, para indicar que una clase implementa una interfaz se


utiliza la palabra reservada implements. La clase debe entonces
implementar todos los métodos definidos por la interfaz o
declararse, a su vez, como una clase abstracta (lo que no suele
ser especialmente útil):

abstract class SinArea implements Figura


{
}

3.5 APLICACIÓN PRÁCTICA CON LA HERENCIA

Se declaran las clases mamíferos, gato y perro, haciendo que gato y


perro sean unos mamíferos (derivados de esta clase), y se ve como a
través de ellos se nombra al animal pero así también se accede a
patas dándole el valor por defecto para esa especie.

import javax.*;
import javax.swing.JOptionPane;

public class Mamifero{


private int patas;
private String nombre;

public void imprimirPatas(){


JOptionPane.showMessageDialog(null," Tiene " + patas + " patas\n",
"Mamifero", JOptionPane.INFORMATION_MESSAGE);
}

public Mamifero(String nombre, int patas){


this.nombre = nombre;
this.patas = patas;
}
}

Compilado Programación II                                                                                                                                                                                                                  49


public class Perro extends Mamifero {
public Perro(String nombre){
super(nombre, 4);
}
}

public class Gato extends Mamifero {


public Gato(String nombre){
super(nombre, 4);
}
}

public class CrearPerro {


public static void main(String[] args) {
Perro perrito = new Perro("Pantaleon");
perrito.imprimirPatas(); /*Está en la clase mamífero*/
}
}

Es importante destacar tres cosas. La primera, es que la


herencia no es un mecanismo esencial en el paradigma de
programación orientada a objetos; en la mayoría de los
lenguajes orientados a objetos basados en prototipos las clases
no existen, en consecuencia tampoco existe la herencia y el
polimorfismo se logra por otros medios. La segunda, es que el
medio preferido para lograr los objetivos de extensibilidad y
reutilización es la agregación o composición. La tercera, es que
en lenguajes con un sistema de tipos débiles, el polimorfismo se
puede lograr sin utilizar la herencia.

Por otra parte y aunque la herencia no es un concepto


indispensable en el paradigma de programación orientada a
objetos, es mucho más que un mecanismo de los lenguajes
basados en clases, porque implica una forma de razonar sobre
cómo diseñar ciertas partes de un programa. Es decir, no sólo
es un mecanismo que permite implementar un diseño, sino que
establece un marco conceptual que permite razonar sobre cómo
crear ese diseño. (Wikipedia)

EJEMPLO
50 Universidad de la Amazonia - Tecnología en Informática y Sistemas
Se tiene la creación de la clase Persona:

public class Persona {


public String nombre;
public int edad;

public void correr(){


/* por implementar */
}
}

y dentro del cuerpo del programa instanciamos una nueva Persona


denominada Esteban:

public class Main {


public static void main(String[] args) {

Persona esteban = new Persona();


// Ahora que esteban es persona, puede correr
esteban.corre();
}
}

EJEMPLO

Imagine que una Persona ha sido expuesta a una extraña radiación y


ahora tiene super poderes, por lo que no deja de ser persona, pero ahora
tiene nuevos comportamientos y estados, por lo que diremos que la nueva
clase SuperHeroe hereda de la clase Persona:

Se tiene el siguiente código en Java

public class SuperHeroe extends Persona{


//Atributos:
public String nombreDeFiccion;

//Metodos:
public void correrMuyRapido(){
//TODO: implementar
}

public void volar(){


//TODO: implementar
}

Compilado Programación II                                                                                                                                                                                                                  51


}

Nota: La palabra clave extends nos indica que SuperHeroe está heredando
o extendiendo a la super clase Persona. Ahora veamos como se comporta
esta nueva clase dentro del cuerpo del programa principal:

public class Main {


public static void main(String[] args) {

// Instanciar al nuevo SuperHeroe:


SuperHeroe superPersona = new SuperHeroe();

//Estas son propiedades de Persona:


superPersona.nombre = "Carlos Kent";
superPersona.edad = 37;

//Esta es propiedad de SuperHeroe:


superPersona.nombreDeFiccion = "Super Carlos";

//Estos son metodos de SuperHeroe:


superPersona.volar();
superPersona.correrMuyRapido();

En resumen Herencia …

¿En qué consiste?

− Existen dos clases, a las que llamaremos padre (superclase o


clase base) e hija (subclase o clase derivada). Al igual que las
herencias en la vida real, la clase hija pasa a tener lo que
tiene la clase padre; Atributos Métodos, Un objeto de la clase
hija es también un objeto de la clase padre.
− En la clase hija se definen las diferencias respecto de la clase
padre.

¿Para qué se usa?

− Para extender la funcionalidad de la clase padre

52 Universidad de la Amazonia - Tecnología en Informática y Sistemas


− Para especializar el comportamiento de la clase padre

Ventajas

− Se ahorra código
− Permite reutilizar código extendiendo su funcionalidad

Desventajas
− Se introduce una fuerte dependencia en la clase hija respecto a la clase padre
− Puede dificultar la reutilización
− Un cambio en la clase padre puede tener efectos imprevistos en las clases hijas
− Un objeto de una clase hija puede tener un comportamiento inconsistente con lo
esperado de un objeto de la clase padre
− Se establece una jerarquía o clasificación. Si cambia el criterio de clasificación puede
acarrear muchas modificaciones. (Herencia)

Compilado Programación II                                                                                                                                                                                                                  53


4. POLIMORFISMO

El término polimorfismo se deriva del riego (poly=muchos:


morphos=forma) y significa “muchas o múltiples formas”, esto
es, la posibilidad que tiene una entidad para referirse a
instancias de clases diferentes en tiempos de ejecución; es
decir, una entidad toma muchas forma. En términos prácticos,
el polimorfismo permite referirse a objetos de diferentes clases
por medio del mismo elemento de programa y realizar la misma
operación de formas diferentes, de acuerdo al objeto a que se
hace referencia en cada momento. Un ejemplo típico de
polimorfismo es la operación comer cuando se aplica a
diferentes tipos de animales; en cada cado la operación de
comer se realiza de forma diferente (Aguilar, 1996).

En programación orientada a objetos se denomina polimorfismo


a la capacidad que tienen los objetos de una clase de responder
al mismo mensaje o evento en función de los parámetros
utilizados durante su invocación. Un objeto polimórfico es una
entidad que puede contener valores de diferentes tipos durante
la ejecución del programa.

En algunos lenguajes, el término polimorfismo es también


conocido como ‘Sobrecarga de parámetros’ ya que las
características de los objetos permiten aceptar distintos
parámetros para un mismo método (diferentes
implementaciones) generalmente con comportamientos distintos
e independientes para cada una de ellas. (Polimorfismo)

EJEMPLO

Se puede crear dos clases distintas: Pez y Ave que heredan de la


superclaseAnimal. La clase Animal tiene el método abstracto
mover que se implementa de forma distinta en cada una de las
subclases (peces y aves se mueven de forma distinta). Entonces,
un tercer objeto puede enviar el mensaje mover a un grupo de
objetos Pez y Ave por medio de una variable de referencia de
54 Universidad de la Amazonia - Tecnología en Informática y Sistemas
clase Animal, haciendo así un uso polimórfico de dichos objetos
respecto del mensaje mover.

El concepto de polimorfismo, desde una perspectiva más


general, se puede aplicar tanto a funciones como a tipos de
datos. Así nacen los conceptos de funciones polimórficas y tipos
polimórficos. Las primeras son aquellas funciones que pueden
evaluarse o ser aplicadas a diferentes tipos de datos de forma
indistinta; los tipos polimórficos, por su parte, son aquellos
tipos de datos que contienen al menos un elemento cuyo tipo no
está especificado (Polimorfismo ). El polimorfismo se puede
establecer mediante sobrecarga, sobre-escritura y enlace
dinámico.

4.1 SOBRECARGA

Este término se refiere al uso del mismo identificador u


operador en distintos contextos y con distintos significados. Si
para cada funcionalidad necesitada fuese necesario escribir un
método, el código resultante sería inmanejable. Supongamos
que los desarrolladores de Java hubiesen creado un método
para escribir en pantalla una cadena de texto, otro diferente
para escribir un entero, otro para un doble, y así para todas las
combinaciones posibles, seria casi imposible conocer dichos
métodos en totalidad. En cambio, con “System.out.print()” o
“System.out.println()” podemos escribir cualquier mensaje en
pantalla.

Este tipo de codificación es permitido gracias a la sobrecarga, la


cual se aplica a métodos y constructores. La sobrecarga de
métodos hace que un mismo nombre pueda representar
distintos métodos con distinto tipo y número de parámetros,
manejados dentro de la misma clase. En el ámbito de la POO, la
sobrecarga de métodos se refiere a la posibilidad de tener dos o
más métodos con el mismo nombre pero distinta funcionalidad.
Es decir, dos o más métodos con el mismo nombre realizan
acciones diferentes y el compilador usará una u otra
dependiendo de los parámetros usados. Esto también se aplica

Compilado Programación II                                                                                                                                                                                                                  55


a los constructores (de hecho, es la aplicación más habitual de
la sobrecarga).

Se puede diferenciar varios métodos sobrecargados a través de


sus parámetros, ya sea por la cantidad, el tipo o el orden de los
mismos.

EJEMPLO

public class Articulo {


private float precio;

public void setPrecio() {


precio = 3.50;
}
public void setPrecio(float nuevoPrecio) {
precio = nuevoPrecio;
}
public void setPrecio(float costo, int porcentajeGanancia) {
precio = costo + (costo * porcentajeGanancia);
}
}

4.2 SOBREESCRITURA

La sobreescritura se aplica a los métodos y está directamente


relacionada a la herencia; se refiere a la redefinición de los
métodos de la clase base en las subclases. Por ejemplo, en la
relación de herencia del ejemplo de las figuras aunque la clase
base “Figura” tiene los métodos “calcularArea” y
“calcularPerimetro”, las subclases “Circulo”, “Cuadrado”,
“Triangulo” y “Rectangulo” redefinen estos métodos ya que el
calculo del área y el perímetro de cada uno de ellos es diferente.

class Figura {
protected double area;
protected double perimetro;

public Figura() {
this.area=0;

56 Universidad de la Amazonia - Tecnología en Informática y Sistemas


this.perimetro=0;
}
public double getArea() {
return area;
}
public double getPerimetro() {
return perimetro;
}
public void calcularArea(){}
public void calcularPerimetro(){}
}
public class Circulo extends Figura {
private double radio;
public Circulo() {
super();
}
public double getRadio() {
return radio;
}
public void setRadio(double radio) {
this.radio = radio;
}
public void calcularArea() {
this.area = Math.PI*Math.pow(this.radio,2.0);
}
public void calcularPerimetro() {
this.perimetro = 2*Math.PI*this.radio;
}
}

4.3 ENLACE DINÁMICO

Esto permite invocar operaciones en objetos obviando el tipo actual de


éstos hasta el momento de ejecutar el código. O sea, nos permite definir
elementos como un tipo e instanciarlos como un tipo heredado. Pero ¿qué
utilidad tiene obviar el tipo de un objeto para luego tomar esta decisión?.

Gracias a que en java la definición de los tipos de objetos se puede


producir por enlazado posterior (late binding), no nos debe preocupar a qué
tipo de elemento le paso un mensaje, ya que el compilador tomará la
decisión sobre qué objeto ejecutará qué método de acuerdo a la forma de
crear la instancia.

Este concepto es bastante complejo de entender, ya que estamos


acostumbrados a definir los elementos de acuerdo a lo que necesitamos.
Es decir, si requiero un entero lo declaro como entero; ¿para que declarar
Compilado Programación II                                                                                                                                                                                                                  57
un elemento como un tipo y luego usarlo como otro?. La respuesta está en
que no siempre se puede determinar exactamente el tipo de elemento que
va a usarse en la ejecución de nuestro programa.

Se debe tener por lo menos una relación de herencia que


permita determinar un tipo base para la declaración, sea cual
sea el subtipo que se instancie. Veamos un ejemplo que nos
aclare un poco las cosas:

class Mamifero {
public void mover() {
System.out.println("Ahora es un mamifero el que se mueve");
}
}

class Perro extends Mamifero {


public void mover() {
System.out.println("Ahora es un perro el que se mueve");
}
}

class Gato extends Mamifero {


public void mover() {
System.out.println("Ahora es un gato el que se mueve");
}
}

public class Polimorfismo {


public static void muevete(Mamifero m) {
m.mover();
}
public static void main(String[] args) {
Gato bisho = new Gato();
Perro feo = new Perro();
muevete(bisho);
muevete(feo);
}
}

58 Universidad de la Amazonia - Tecnología en Informática y Sistemas


Se tiene que el método “muevete” llama al método mover de un
mamífero y aunque no sabe con qué clase de mamífero trata,
funciona y se llama al método correspondiente al objeto
específico que lo llama (es decir, primero un gato y luego un
perro). Si no existiera el enlace dinámico, se tendría que crear
un método “muevete” para los mamíferos de tipo “Gato” y otro
para los de tipo “Perro”. Veamos otro ejemplo donde las
instancias se crean de forma aleatoria:

public abstract class Instrumento {


public Instrumento() { }
public abstract void tocar();
public abstract void tocar(String nota);
public abstract void afinar();
}

public class Cuerda extends Instrumento{


public Cuerda() {}
public void afinar() {
System.out.println("Cuerda.afinar()");
}
public void tocar() {
System.out.println("Cuerda.tocar()");
}
public void tocar(String nota){
System.out.println("Cuerda.tocar()"+nota);
}
}

public class Percusion extends Instrumento{


public Percusion() {}
public void afinar() {
System.out.println("Percusion.afinar()");
}
public void tocar() {
System.out.println("Percusion.tocar()");
}
public void tocar(String nota){
System.out.println("Percusion.tocar()"+nota);

Compilado Programación II                                                                                                                                                                                                                  59


}
}

public class Viento extends Instrumento{


public Viento() {}
public void afinar() {
System.out.println("Viento.afinar()");
}
public void tocar() {
System.out.println("Viento.tocar()");
}
public void tocar(String nota){
System.out.println("Viento.tocar()"+nota);
}
}

public class LigaduraDinamica {


public static void main(String[] args){
String[] notas = {"Do","Re","Mi","Fa","Sol","La","Si"};
Instrumento orquesta[] = new Instrumento[10];

for(int i=0;i&lt;10;i++){
orquesta[i]=generarInstrumento(new
java.util.Random().nextInt(3));
}

for(int i=0;i&lt;10;i++){
afinarInstrumento(orquesta[i]);
}

for(int i=0;i&lt;10;i++){
tocarInstrumento(orquesta[i]);
}

for(int i=0;i&lt;10;i++){
tocarInstrumento(orquesta[i],notas[i%7]);
}
}

60 Universidad de la Amazonia - Tecnología en Informática y Sistemas


public static Instrumento generarInstrumento(int i){
switch(i){
default:
case 0:
return new Viento();
case 1:
return new Percusion();
case 2:
return new Cuerda();
}
}

public static void afinarInstrumento(Instrumento o){


o.afinar();
}

public static void tocarInstrumento(Instrumento o){


o.tocar();
}

public static void tocarInstrumento(Instrumento o,String


nota){
o.tocar(nota);
}
}

Se tiene que el método “generarInstrumento” crea


aleatoriamente las instancias de los diferentes tipos de
instrumentos y que el arreglo de elementos del tipo de
instrumentos es llenado con diferentes elementos de los cuales
sólo sabemos que son objetos basados en “Instrumento”. Sin
embargo, los métodos “tocarInstrumento” y “afinarInstrumento”
que reciben como parámetro un Instrumento llaman
adecuadamente a los métodos “afinar” o “tocar” según la
instancia que reciben. (Conceptos sobre polimorfismo y programación
orientada a objetos)

Compilado Programación II                                                                                                                                                                                                                  61


4.4 FUNCIONES VIRTUALES Y FUNCIONES ABSTRACTAS

En programación orientada a objetos (POO), una función virtual


o método virtual es una función cuyo comportamiento, al ser
declarado "virtual", es determinado por la definición de una
función con la misma cabecera en alguna de sus subclases.
Este concepto es una parte muy importante del polimorfismo en
la POO. El concepto de función virtual soluciona los siguientes
problemas:

En POO, cuando una clase derivada hereda de una clase base,


un objeto de la clase derivada puede ser referido (o coercionado)
tanto como del tipo de la clase base como del tipo de la clase
derivada. Si hay funciones de la clase base redefinidas por la
clase derivada, aparece un problema cuando un objeto derivado
ha sido cohercionado como del tipo de la clase base. Cuando un
objeto derivado es referido como del tipo de la base, el
comportamiento de la llamada a la función deseado es ambiguo.
Distinguir entre virtual y no virtual sirve para resolver este
problema. Si la función en cuestión es designada "virtual", se
llamará a la función de la clase derivada (si existe). Si no es
virtual, se llamará a la función de la clase base.

EJEMPLO

Por ejemplo, una clase base Animal podría tener una función
virtual come. La subclase Pez implementaría come() de forma
diferente que la subclase Lobo, pero se podría invocar a come()
en cualquier instancia de una clase referida como Animal, y
obtener el comportamiento de come() de la subclase específica.

Esto permitiría a un programador procesar una lista de objetos


de la clase Animal, diciendo a cada uno que coma (llamando a
come()), sin saber qué tipo de animales hay en la lista (Función
Virtual ). Tampoco tendría que saber cómo come cada animal, o
cuántos tipos de animales puede llegar a existir. El siguiente, es
un ejemplo en C++:

# include <iostream>

62 Universidad de la Amazonia - Tecnología en Informática y Sistemas


class Animal
{
public:
virtual void come() { std::cout << "Yo como como un animal
genérico.\n"; }
virtual ~Animal() {}
};

class Lobo : public Animal


{
public:
void come() { std::cout << "¡Yo como como un lobo!\n"; }
virtual ~Lobo() {}
};

class Pez : public Animal


{
public:
void come() { std::cout << "¡Yo como como un pez!\n"; }
virtual ~Pez() {}
};

class OtroAnimal : public Animal


{
virtual ~OtroAnimal() {}
};

int main()
{
Animal *unAnimal[4];
unAnimal[0] = new Animal();
unAnimal[1] = new Lobo();
unAnimal[2] = new Pez();
unAnimal[3] = new OtroAnimal();

for(int i = 0; i < 4; i++) {


unAnimal[i]->come();
}

Compilado Programación II                                                                                                                                                                                                                  63


for (int i = 0; i < 4; i++) {
delete unAnimal[i];
}
return 0;
}
Salida con el método virtual come:
Yo como como un animal genérico.
¡Yo como como un lobo!
¡Yo como como un pez!
Yo como como un animal genérico.

Salida sin el método virtual come:


Yo como como un animal genérico.
Yo como como un animal genérico.
Yo como como un animal genérico.
Yo como como un animal genérico.

4.4.1 FUNCIONES VIRTUALES

El polimorfismo en tiempo de ejecucion es logrado por una


combinacion de dos características: 'Herencia y funciones
virtuales". Una función virtual es una función que es declarada
como 'virtual' en una clase base y es redefinida en una o mas
clases derivadas. Ademas, cada clase derivada puede tener su
propia version de la funcion virtual. Lo que hace interesantes a
las funciones virtuales es que sucede cuando una es llamada a
través de un puntero de clase base (o referencia). En esta
situacion, C++ determina a cual version de la funcion llamar
basándose en el tipo de objeto apuntado por el puntero. Y, esta
determinacion es hecha en 'tiempo de ejecucion'.

Además, cuando diferentes objetos son apuntados, diferentes


versiones de la funcion virtual son ejecutadas. En otras
palabras es el tipo de objeto al que esta siendo apuntado (no el
tipo del puntero) lo que determina cual version de la funcion
virtual sera ejecutada. Ademas, si la clase base contiene una
funcion virtual, y si dos o mas diferentes clases son derivadas
de esa clase base, entonces cuando tipos diferentes de objetos

64 Universidad de la Amazonia - Tecnología en Informática y Sistemas


estan siendo apuntados a traves de un puntero de clase base,
diferentes versiones de la funcion virtual son ejecutadas. Lo
mismo ocurre cuando se usa una refrencia a la clase base.

Se declara una funcion como virtual dentro de la clase base


precediendo su declaracion con la palabra clave virtual. Cuando
una funcion virtual es redefinida por una clase derivada, la
palabra clave 'virtual' no necesita ser repetida ( aunque no es
un error hacerlo ).

Una clase que incluya una funcion virtual es llamada una 'clase
polimórfica'. Este término también aplica a una clase que
hereda una clase base conteniendo una funcion virtual.
Examine este corto programa, el cual demuestra el uso de
funciones virtuales:

// Un ejemplo corto que usa funciones virtuales


#include <iostream>
using namespace std;

class base {
public:
virtual void quien() {cout << "Base" << endl;} // especificar una
clase virtual
};

class primera_d : public base {


public:
// redefinir quien() relativa a primera_d
void quien() {cout << "Primera derivacion" << endl;}
};

class segunda_d : public base {


public:
// redefinir quien relativa a segunda_d
void quien() {cout << "Segunda derivacion" << endl;}
};

int main()

Compilado Programación II                                                                                                                                                                                                                  65


{
base obj_base;
base *p;

primera_d obj_primera;
segunda_d obj_segundo;

p = &obj_base;
p->quien(); // acceder a quien() en base

p = &obj_primera;
p->quien(); // acceder a quien() en primera_d

p = &obj_segunda;
p->quien(); // acceder a quien() en segunda_d

return 0;
}

Este programa produce la siguiente salida:

Base
Primera derivacion
Segunda derivación

Examinemos el programa en detalle para comprender como


funciona:

En 'base', la funcion 'quien()' es declarada como 'virtual'. Esto


significa que la funcion puede ser redefinida en una clase
derivada. Dentro de ambas 'primera_d' y 'segunda_d', 'quien()' es
redefinida relativa a cada clase. Dentro de main(), cuatro
variables son declaradas: 'obj_base', el cual es un objeto del tipo
'base'; 'p' el cual un un puntero a objetos del tipo 'base';
'obj_primera' y 'obj_segunda', que son objetos de dos clases
derivadas. A continuacion 'p' es asignada con la direccion de
'obj_base', y la funcion quien() es llamada.

66 Universidad de la Amazonia - Tecnología en Informática y Sistemas


Como quien() es declarada como virtual, C++ determina en
tiempo de ejecucion, cual version de quien() es referenciada por
el tipo del objeto apuntado por 'p'. En este caso, 'p' apunta a un
objeto del tipo 'base', asi que es la version de 'quien()' declarada
en 'base' la que es ejecutada. A continuacion, se le asigna a 'p'
la direccion de 'obj_primera'. Recuerde que un puntero de la
clase base puede referirse a un objeto de cualquier clase
derivadas. Ahora, cuando quien() es llamada, C++ nuevamente
comprueba para ver que tipo de objeto es apuntado por 'p' y
basado en su tipo, determina cual version de quien() llamar.

Como 'p' apunta a un objeto del tipo 'obj_primera', esa version


de quien() es usada. De ese mismo modo, cuando 'p' es
asignada con la direccion de 'obj_segunda', la version de quien()
declarada en 'segunda_d' es ejecutada.

RECUERDE: "Es determinado en tiempo de ejecucion cual


version de una funcion virtual en realidad es llamada. Ademas,
esta determinacion es basada solamente en el tipo del objeto
que esta siendo apuntado por un puntero de clase base."

Una funcion virtual puede ser llamada normalmente, con la


sintaxis del operador estandar de 'objeto.' Esto quiere decir que
en el ejemplo precedente, no seria incorrecto sintacticamente
acceder a quien() usando esta declaracion: obj_primera.quien();

Sin embargo, llamar a una funcion virtual de esta manera


ignora sus atributos polimórficos. Es solo cuando una funcion
virtual es accesada por un puntero de clase base que el
polimorfismo en tiempo de ejecucion es logrado.

A primera vista, la redefinicion de una funcion virtual en una


clase derivada parece ser una forma especial de sobrecarga de
funcion. Sin embargo, este no es el caso. De hecho, los dos
procesos son fundamentalmente diferentes. Primero, una
funcion sobrecargada debe diferir en su tipo y/o numero de
parametros, mientras que una funcion virtual redefinida debe
tener exactamente el mismo tipo y numero de parametros. De

Compilado Programación II                                                                                                                                                                                                                  67


hecho, los prototipos para una funcion virtual y sus
redefiniciones debe ser exactamente los mismos.

Si los prototipos difieren, entonces la funcion simplemente se


considera sobrecargada, y su naturaleza virtual se pierde. Otra
restriccion es que una funcion virtual debe ser un miembro, no
una funcion 'friend', de la clase para la cual es definida. Sin
embargo, una funcion virtual puede ser una funcion 'friend' de
otra clase. Tambien, es permisible para funciones destructores
ser virtuales, pero esto no es asi para los constructores.

"Cuando una funcion virtual es redefinida en una clase


derivada, se dice que es una funcion 'overriden' ( redefinida )"

Por las restricciones y diferencias entre sobrecargar funciones


normales y redefinir funciones virtuales, el termino 'overriding'
es usado para describir la redefinicion de una funcion virtual.

4.4.2 FUNCIONES VIRTUALES PURAS Y CLASES


ABSTRACTAS

Una funcion virtual que no es redefinida en una clase derivada


es llamada por un objeto de esa clase derivada, la version de la
funcion como se ha definido en la clase base es utilizada. Sin
embargo, en muchas circunstancias, no habra una declaracion
con significado en una funcion virtual dentro de la clase base.
Por ejemplo, en la clase base 'figura' usada en el ejemplo
anterior, la definicion de 'mostrar_area()' es simplemente un
sustituto sintetico. No computara ni mostrara el area de ningun
tipo de objeto. Como vera cuando cree sus propias librerias de
clases no es poco comun para una funcion virtual tener una
definicion sin significado en el contexto de su clase base.

Cuando esta situacion ocurre, hay dos manera en que puede


manejarla. Una manera, como se muestra en el ejemplo, es
simplemente hacer que la funcion reporte un mensaje de
advertencia. Aunque esto puede ser util en ocasiones, no es el
apropiado en muchas circunstancias. Por ejemplo, puede haber
funciones virtuales que simplemente deben ser definidas por la
68 Universidad de la Amazonia - Tecnología en Informática y Sistemas
clase derivada para que la clase derivada tenga algun
significado.

Considere la clase 'triangulo'. Esta no tendria significado si


'mostrar_area()' no se encuentra definida. En este caso, usted
desea algun metodo para asegurarse de que una clase derivada,
de hecho, defina todas las funciones necesarias. En C++, la
solucion a este problema es la 'funcion virtual pura.'

Una 'funcion virtual pura' es una función declarada en una


clase base que no tiene definicion relativa a la base. Como
resultado, cualquier tipo derivado debe definir su propia version
-- esta simplemente no puede usar la version definida en la
base. Para declarar una funcion virtual pura use esta forma
general:

virtual 'tipo' 'nombre_de_funcion'(lista_de_parametros) = 0;

Aqui, 'tipo' es el tipo de retorno de la funcion y


'nombre_de_funcion' es el nombre de la funcion. Es el = 0 que
designa la funcion virtual como pura. Por ejemplo, la siguiente
version de 'figura', 'mostrar_area()' es una funcion virtual pura.

class figura {
double x, y;
public:
void set_dim(double i, double j=0) {
x = i;
y = j;
}

virtual void mostrar_area() = 0; // pura


};

Declarando una funcion virtual como pura, se fuerza a


cualquier clase derivada a definir su propia implementación. Si
una clase falla en hacerlo, el compilador reportara un error. Por
ejemplo, intente compilar esta version modificando del

Compilado Programación II                                                                                                                                                                                                                  69


programa de figuras, en el cual la definición de mostrar_area()
ha sido removida de la clase 'circulo':

/*
Este programa no compilara porque la clase
circulo no redefinio mostrar_area()
*/

#include <iostream>
using namespace std;

class figura {
protected:
double x, y;
public:
void set_dim(double i, double j=0) {
x = i;
y = j;
}
virtual void mostrar_area() = 0; // pura
};

class triangulo : public figura {

public:
void mostrar_area() {
cout << "Triangulo con alto ";
cout << x << " y base " << y;
cout << " tiene un area de ";
cout << x * 0.5 * y << ".\n";
}
};
class rectangulo : public figura {

public:
void mostrar_area() {
cout << "Rectangulo con dimensiones ";
cout << x << " x " << y;
cout << " tiene un area de ";

70 Universidad de la Amazonia - Tecnología en Informática y Sistemas


cout << x * y << ".\n";
};
};

class circulo : public figura {


// la no definicion de mostrar_area() causara un error
};

int main()
{
figura *p; // crear un puntero al tipo base

triangulo t; // crear objetos de tipos derivada


rectangulo r;
circulo c; // ilegal -- no puedo crearla!

p = &t;
p->set_dim(10.0, 5.0);
p->mostrar_area();

p = &r;
p->set_dim(10.0, 5.0);
p->mostrar_area();

return 0;
}

Si una clase tiene al menos una funcion virtual pura, entonces


esa clase se dice que es 'abstracta'. Una clase abstracta tiene
una caracteristica importante: No puede haber objetos de esa
clase. En vez de eso, una clase abstracta debe ser usada solo
como una base que otras clases heredaran. La razon por la cual
una clase abstracta no puede ser usada para declarar un objeto
es, por supuesto, que una o mas de sus funciones no tienen
definicion. Sin embargo, incluso si la clase base es abstracta, la
puede usar aun para declarar punteros o referencias, los cuales
son necesarios para soportar el polimorfismo en tiempo de
ejecucion. (Funciones Virtuales)

Compilado Programación II                                                                                                                                                                                                                  71


4.5 APLICACIÓN PRÁCTICA CON EL POLIMORFISMO

En el siguiente ejemplo se hace uso del lenguaje C++ para


ilustrar el polimorfismo. Se observa a la vez el uso de las
funciones virtuales puras, como se les conoce en C++, estas
funciones constituyen una interfaz más consistente cuando se
trabaja con una jerarquía de clases, puesto que hacen posible el
enlace durante la ejecución. Sin embargo como se verá, para
que el polimorfismo funcione no es una condición obligatoria
que todas las funciones en la clase base sean declaradas como
virtuales.

La siguiente figura representa el diagrama de clases UML, que


describe gráficamente la relación entre la clase base Figura y
sus posibles clases derivadas, y la entidad que utiliza esta
estructura: la Aplicación, también identificado como objeto
Cliente.

Se tiene:

#include<iostream>
using namespace std;

class Figura {
72 Universidad de la Amazonia - Tecnología en Informática y Sistemas
private:
float base;
float altura;
public:
void captura();
virtual unsigned float perimetro()=0;
virtual unsigned float area()=0;
};

class Rectangulo: public Figura {


public:
void imprime();
unsigned float perimetro(){return 2*(base+altura);}
unsigned float area(){return base*altura;}
};

class Triangulo: public Figura {


public:
void muestra();
unsigned float perimetro(){return 2*altura+base}
unsigned float area(){return (base*altura)/2;}
};

void Figura::captura()
{
cout << "CALCULO DEL AREA Y PERIMETRO DE UN
TRIANGULO ISÓSCELES Y UN RECTANGULO:" << endl;
cout << "escribe la altura: ";
cin >> altura;
cout << "escribe la base: ";
cin >> base;
cout << "EL PERIMETRO ES: " << perimetro();
cout << "EL AREA ES: " << area();
getch();
return 0;
}

Compilado Programación II                                                                                                                                                                                                                  73


5.RELACIONES EN EL MODELO OO

Tanto la asociación, agregación, composición y dependencia son


formas de representar las relaciones que existen entre clases.

5.1 ASOCIACIÓN

La relación entre clases conocida como Asociación, permite


asociar objetos que colaboran entre si. Cabe destacar que no es
una relación fuerte, es decir, el tiempo de vida de un objeto no
depende del otro.

Ejemplo:

Un cliente puede tener


asociadas muchas Ordenes
de Compra, en cambio una orden de compra solo puede tener
asociado un cliente.

5.2 AGREGACIÓN

Para modelar objetos complejos, n bastan los tipos de datos


básicos que proveen los lenguajes: enteros, reales y secuencias
de caracteres. Cuando se requiere componer objetos que son
instancias de clases definidas por el desarrollador de la
aplicación, tenemos dos posibilidades:

− Por Valor: Es un tipo de relación estática, en donde el tiempo


de vida del objeto incluido esta condicionado por el tiempo de
vida del que lo incluye. Este tipo de relación es comunmente
llamada Composición (el Objeto base se contruye a partir del
objeto incluido, es decir, es "parte/todo").

− Por Referencia: Es un tipo de relación dinámica, en donde el


tiempo de vida del objeto incluido es independiente del que lo
incluye. Este tipo de relación es comunmente llamada
74 Universidad de la Amazonia - Tecnología en Informática y Sistemas
Agregación (el objeto base utiliza al incluido para su
funcionamiento).

Un Ejemplo es el siguiente:
En donde se destaca que:

− Un Almacen posee Clientes y


Cuentas (los rombos van en
el objeto que posee las
referencias).
− Cuando se destruye el Objeto Almacen también son
destruidos los objetos Cuenta asociados, en cambio no son
afectados los objetos Cliente asociados.
− La composición (por Valor) se destaca por un rombo relleno.
− La agregación (por Referencia) se destaca por un rombo
transparente.
− La flecha en este tipo de relación indica la navegabilidad del
objeto refereniado. Cuando no existe este tipo de
particularidad la flecha se elimina.
(Diseño de clases)

5.3 COMPOSICIÓN

Composición es una forma fuerte de composición donde la vida de la clase


contenida debe coincidir con la vida de la clase contenedor. Los
componentes constituyen una parte del objeto compuesto. De esta forma,
los componentes no pueden ser compartidos por
varios objetos compuestos. La supresión del objeto
compuesto conlleva la supresión de los
componentes. El símbolo de composición es un
diamante de color negro colocado en el extremo en
el que está la clase que representa el “todo”
(Compuesto).

Veamos un ejemplo de composición:

Tenemos una clase Empresa.

− Un objeto Empresa está a su vez compuesto por


uno o varios objetos del tipo empleado.

Compilado Programación II                                                                                                                                                                                                                  75


− El tiempo de vida de los objetos Empleado depende del tiempo de vida
de Empresa, ya que si no existe una Empresa no pueden existir sus
empleados.

5.4 APLICACIÓN DE LAS RELACIONES

Por ejemplo el siguiente diagrama:

La clase Persona tiene una relación de composición con la clase


Domicilio.

Conceptualmente esto significa que los domicilios son una parte


inseparable de la persona, por lo que si no existiera una
persona entonces el domicilio de la misma debería desaparecer.

Si analizamos más en profundidad encontramos también que, si


hubiera que persistir esta relación en una base datos
tendríamos una tabla Domicilios cuyo ID sería IdPersona, y una
tabla Personas con el mismo ID.
El hecho de que la tabla Domicilios no tenga su propio ID sino
el de la otra tabla significa que cada registro de la tabla no tiene
el peso propio suficiente, que depende 100% de la existencia del
mismo ID en la tabla de Personas.

76 Universidad de la Amazonia - Tecnología en Informática y Sistemas


Si se llegase a borrar un registro de la tabla Personas habría
que borrar su correspondiente registro de la tabla Domicilios
para mantener la integridad de la información.

Por esta razón también se dice que la relación de composición


es una relación fuerte, ya que una instancia arrastra a la otra
en caso de eliminación (tanto de objetos en memoria como de
registros en base de datos).

Ahora, es válido preguntarse ¿por que razón si es algo


inseparable de la persona no lo pongo como un atributo más de la
clase persona, por ejemplo de tipo string y no me complico tanto?

Efectivamente la clase Domicilio es un atributo de la clase


Persona, y justamente la línea que las conecta es lo que indica
la presencia del atributo. Domicilio existe como clase aparte
porque en realidad no es un simple string sino un conjunto de
atributos, por ejemplo: calle, localidad, numeración, piso,
departamento, etc. Todos esos atributos forman parte de una
entidad, el Domicilio, y no sería correcto dejarlos sueltos dentro
de la clase Persona. Por eso también se persisten en tablas
separadas si fuera necesario.

La clase Persona tiene una relación de Agregación con Categoría.

Conceptualmente esto significa que las categorías existen


independientemente de la persona que la tenga asignada. En el
modelo conceptual esto se corresponde con un enunciado como
"una persona puede tener una categoría pero una categoría
puede estar presente en muchas personas".

En un modelo de persistencia relacional tendríamos por un lado


la tabla Categorías con su IdCategoría y la tabla Persona con un
IdCategoría que señale la relación entre ambas tablas.

A diferencia de la composición, en la agregación la clave


primaria de la tabla Categorías es independiente de la clave
primaria de la persona, lo cual significa que se puede eliminar

Compilado Programación II                                                                                                                                                                                                                  77


un registro de Personas sin que ello afecte la integridad de la
tabla Categorías.

Ambos tipos de relación muestran que la forma del objeto


(persona en este caso) está formado por partes externas.

La clase Persona tiene una relación de Dependencia con


Postulación.

Conceptualmente esto significa que la Postulación es un objeto


que la Persona utiliza para algún fin, dentro de alguna
operación que ella realice (por ejemplo Postularse a un cargo).
Pero una Persona no tiene en su interior una Postulación, sino
que solo lo utiliza para realizar ciertas operaciones.

Esto es lo más importante y diferenciador respecto de las otras


dos relaciones; aquí se pone énfasis en el uso de clases dentro
de operaciones, es decir, para que una Persona pueda enviar
una postulación depende la clase Postulación , quien es capaz
realmente de realizar esa operación. Al no tratarse de una
relación que vincula la forma de los objetos, no existe una forma
de persistir esta relación.

La clase Persona tiene una relación de Asociación con Sucursal.

Conceptualmente la asociación en un diagrama de clases


implica transitividad y bidirección de clases. Por ejemplo una
persona tiene como atributo interno a una Sucursal, pero (y
aquí está la diferencia) una Sucursal también tiene un atributo
de tipo Persona; la cardinalidad de la asociación indicará si
Sucursal tiene una o muchas instancias de Persona, con lo cual
en realidad el atributo de Sucursal podría ser una Lista o Vector
de Personas.

Otra característica fundamental es que la vida de las instancias


de ambas clases no dependen una de la otra.

En un modelo de persistencia relacional podrían suceder dos


cosas: si se trata de una cardinalidad de 1 a 1 tendríamos la

78 Universidad de la Amazonia - Tecnología en Informática y Sistemas


tabla Personas con su IdPersona más un IDSucusal y la tabla
Sucursales con su IdSucursal más un IdPersona.

Cualquier otra cardinalidad requerirá la tabla Personas y


Sucursales con sus Id individuales más una tabla que unifique
ambas entidades (tabla de relación) con los campos IdPersona e
IdSucursal, la cual permite la navegación en dos direcciones sin
invadir a ninguna de las tablas reales.

El caso especial se presenta cuando en una asociación es


necesario reflejar atributos de información. Por ejemplo, es
necesario registrar la fecha de inicio y la fecha de fin de la
vinculación entre empleados y sucursales.

Desde el punto de
vista de la
persistencia no es
una complicación ya
que la tabla
intermedia que
vincula a Personas y
Sucursales tendrá
más campos de
información.

Pero desde el punto


de vistas de entidades hay un cambio más importante: es
necesario crear una nueva entidad. Si un vínculo necesita
guardar información deja de ser un vínculo y pasa a ser una
entidad nueva, con derecho a tener su propio nombre (no
simplemente la unión de los nombres Persona y Sucursal)
porque en el paradigma orientado a objetos todo lo que tenga
atributos (características) debe ser una entidad. Sin embargo en
el modelo de persistencia la tabla intermedia sí suele tener por
nombre simplemente la unión de las dos tablas.

Compilado Programación II                                                                                                                                                                                                                  79


Lo que tiene de particular esta entidad es que solo tiene sentido
si existen las dos partes, con lo cual en el modelo de
persistencia no debe tener clave primaria a menos que esto no
sea cierto y la información del vínculo deba persistir más allá de
la existencia de las partes que participaron (si así lo dice el
negocio...). En este supuesto sí correspondería agregarle una
clave primaria a la tabla intermedia.

La implementación de esta entidad intermedia puede resolverse


con una clase "TiempoEnSucursal", la cual no tendrá un
identificador propio, pero tendrá una propiedad de tipo
Sucursal y otra de tipo Persona (además de la fecha de inicio y
fecha de fin propias de la clase).

80 Universidad de la Amazonia - Tecnología en Informática y Sistemas


Por último, estas propiedades de Sucursal y Persona deberían
provenir desde afuera de la clase PasoPorSucursal, es decir, por
medio de algún constructor o en el "set" de las propiedades.
Para finalizar se presenta la implementación de las clases donde
se puede ver en detalle como se aplican los tres tipos de
relaciones (Ejemplos prácticos de Asociación, Agregación, Composición y
Dependencia con C# .Net).

Compilado Programación II                                                                                                                                                                                                                  81


6. REFERENCIAS

− Programación Orientada a Objetos . (s.f.). Obtenido de


http://www.ciberaula.com/articulo/tecnologia_orientada_objetos/
− Programación, E. d.-A. (Ed.). (2007). Tema 8 POO. Obtenido de
http://webdelprofesor.ula.ve/ingenieria/hyelitza/materias/programaci
on2/oxo/ProfaYusneyi_Tema8_POOClasesyObjetos.pdf
− POO, V. d. (s.f.). Obtenido de http://android-linux.net/12-
desarrollo/22-ventajas-de-la-programacion-orientada-a-objetos-poo
− Aguilar, L. J. (1996). Programación Orientada a Objetos . España .
− Wikipedia. (s.f.). Obtenido de
http://es.wikipedia.org/wiki/Lenguaje_orientado_a_objetos
− Herencia de clases. (s.f.). Obtenido de
http://www.cristalab.com/tutoriales/programacion-orientada-a-
objetos-herencia-de-clases-c261l/
− Introducción a la POO. (s.f.). Obtenido de
http://www.docentes.unal.edu.co/jaagredab/docs/Introducci%3Fn.A.L
a.Programaci%3Fn.Orientada.A.Objetos.-.Java.pdf
− Conceptos sobre polimorfismo y programación orientada a objetos.
(s.f.). Obtenido de
http://danubuntu.wordpress.com/2008/07/30/conceptos-sobre-
polimorfismo-y-programacion-orientada-a-objetos/
− (s.f.).
− (s.f.). Obtenido de Principios de la POO:
http://es.scribd.com/doc/17041118/1-Principios-de-La-POO
− (s.f.). Recuperado el 20 de Octubre de 2013, de Conceptos de objetos y
clases en Java:
http://www.aprenderaprogramar.com/index.php?option=com_content
&id=411:conceptos-de-objetos-y-clases-en-java-definicion-de-instancia-
ejemplos-cu00619b&Itemid=188
− (s.f.). Obtenido de Wikipedia:
http://es.wikipedia.org/wiki/Herencia_(informática)
− (s.f.). Obtenido de Herencia:
http://www.fdi.ucm.es/profesor/gmendez/docs/prog0607/Tema4-
Herencia.pdf
− (s.f.). Obtenido de Herencia simple y múltiple en Python:
http://www.codejobs.biz/es/blog/2013/05/13/herencia-simple-y-
multiple-en-python
− (s.f.). Obtenido de CLASES EN C++:
http://dis.unal.edu.co/~fgonza/courses/2003/poo/c++.htm
− (s.f.). Obtenido de Polimorfismo:
http://damian02.wordpress.com/polimorfismo-poo/

82 Universidad de la Amazonia - Tecnología en Informática y Sistemas


− (s.f.). Obtenido de Polimorfismo :
http://es.wikipedia.org/wiki/Polimorfismo_(informática)
− (s.f.). Obtenido de Funciones Virtuales:
http://es.wikibooks.org/wiki/Programación_en_C%2B%2B/Funciones_
virtuales
− (s.f.). Obtenido de Función Virtual :
http://es.wikipedia.org/wiki/Función_virtual
− (s.f.). Obtenido de Ejemplos prácticos de Asociación, Agregación,
Composición y Dependencia con C# .Net:
http://alumnosdc.blogspot.com/2013/05/agregacion-composicion-y-
dependencia.html
− (s.f.). Obtenido de Diseño de clases:
http://users.dcc.uchile.cl/~psalinas/uml/modelo.html

Compilado Programación II                                                                                                                                                                                                                  83

También podría gustarte