Programacion Orientada A Objetos
Programacion Orientada A Objetos
Programacion Orientada A Objetos
I
Conceptos Fundamentales de Programación Orientada a Objetos
La programación orientada a objetos 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.
Por la creciente tendencia de crear programas cada vez más grandes y complejos los
desarrolladores crearon una nueva forma de programar con la capacidad de 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
filosofía y nuevos conceptos que tiene. La POO se basa en la división del programa en
pequeñas unidades lógicas de código denominadas objetos.
La programación orientada a objetos o POO (OOP ‐ Object Oriented Programming‐ 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. Está basado en varias técnicas, incluyendo
herencia, abstracción, polimorfismo y encapsulamiento. 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.
Según el concepto vertido por Grady Booch, la POO se define de la siguiente manera:
“La POO es un método de implementación en el 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 miembro de una jerarquía
de clases unidas mediante relaciones de herencia”
Así, se puede notar que la programación orientada a objetos tal cual su nombre lo indica
trabaja exclusivamente con objetos y que cada uno de estos serán instancias de determinadas
clases y que estas se relacionan unas con otras mediante la herencia.
Ventajas de un lenguaje orientado a objetos.
• Fomenta la reutilización y extensión del código.
• Permite crear sistemas más complejos.
• Relacionar el sistema al mundo real.
Dossier Programación III – Lic. Gladys Chuquimia Página 1
• 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.
1.3.1. Abstracción.
La abstracción se conoce también como el proceso de generalización en el que se quita todas
las propiedades y acciones de un objeto extras que tenga el objeto para dejar solamente
aquellas que sean necesarias.
En otras palabras “abstracción” significa filtrar las propiedades y operaciones de un objeto
hasta que queden solamente aquellas que necesitamos.
Según Booch, la abstracción es la: “Supresión intencionada, u ocultamiento, de algunos
detalles de un proceso o artefacto, con el objeto de destacar de manera más clara otros
aspectos, detalles o estructuras”.
1.3.2. Encapsulación
Es la acción referida a “empaquetar” en una clase los datos (propiedades) y el código
(métodos) que opera sobre estos datos.
El encapsulamiento está directamente ligado a las características de caja negra que deben
tener los programas OO, dado que cuando utilizamos un objeto no necesitamos conocer todos
los detalles de la implementación; por lo cual es una buena práctica restringir el acceso a los
datos y a la información interna de sus métodos, a esto se denomina ocultamiento de datos o
encapsulación.
1.3.3. Objetos.
Existen muchas definiciones que se le ha dado al Objeto. Primero empecemos entendiendo
que es un objeto del mundo real. Un objeto del mundo real es cualquier cosa que vemos a
nuestro alrededor. Todo objeto del mundo real tiene 2 componentes: características y
comportamiento.
Por ejemplo, los automóviles tienen características (marca, modelo, color, velocidad máxima,
etc.) y comportamiento (frenar, acelerar, retroceder, llenar combustible, cambiar llantas, etc.).
Los Objetos de Software, al igual que los objetos del mundo real, también tienen
características y comportamientos. Un objeto de software mantiene sus características en una
Dossier Programación III – Lic. Gladys Chuquimia Página 2
o más "variables", e implementa su comportamiento con "métodos". Un método es una
función o subrutina asociada a un objeto
Un objeto puede representarse gráficamente de las siguientes maneras:
Nombre del Objeto: Nombre de Clase
Características ‐ Atributos
Comportamiento ‐ Métodos
b) UML
a) Taylor
1.3.4. Clases.
Es una descripción de un conjunto de objetos: Consta de Métodos y Datos. Es un TDA1 definido
por el usuario que determina las estructuras de datos y sus operaciones asociadas. En POO,
una clase no solo tiene el objetivo de categorizar una colección de elementos sino también el
de servir como plantilla para crear objetos.
Todos los objetos con estados similares y el mismo comportamiento se agrupan en clases.
1.3.5. Mensajes.
Todos los objetos se comunican entre sí mediante el paso de mensajes, y está referido a la
ejecución de un método asociado con el objeto que lo llama. Luego para enviar mensajes se
estipula el nombre del objeto y la acción que se requiere poner en ejecución. En este punto el
método definido especifica cómo se ejecuta el mensaje.
1.3.6. Encapsulamiento.
Es la acción referida a “empaquetar” en una clase los datos (propiedades) y el código
(métodos) que opera sobre estos datos.
El encapsulamiento está directamente ligado a las características de caja negra que deben
tener los programas OO, dado que cuando utilizamos un objeto no necesitamos conocer todos
los detalles de la implementación; por lo cual es una buena práctica restringir el acceso a los
datos y a la información interna de sus métodos, a esto se denomina ocultamiento de datos o
encapsulación.
1
Tipo de Dato Abstracto
Dossier Programación III – Lic. Gladys Chuquimia Página 3
1.3.7. Herencia.
Se la define como el mecanismo que se emplea para crear nuevas clases a partir de clases
existentes, que fomenta la reutilización de código.
El principio en que basa la división de clases en la herencia es la jerarquía (características
comunes).
La herencia supone una clase base y una jerarquía de clases que contienen las clases derivadas
de la clase base, es así como las clases derivadas pueden heredar todas las características de la
clase pudiendo añadir cada una de estas subclases su propio código especial y datos propios.
Las clases que heredan propiedades de una clase base pueden a su vez servir como
definiciones base de otras clases; a su vez las jerarquías de clases se organizan en forma de
árbol.
Existen dos tipos de herencia: Simple y múltiple. En la herencia simple cada clase tiene como
máximo una sola clase base.
Polígono
En la herencia múltiple una clase derivada puede heredar todas las características asociadas
con más de una clase base o superclase.
Persona
Profesor Investigador
Profesor Universitario
1.3.8. Polimorfismo.
Es la habilidad de enviar el mismo mensaje a objetos de diferentes clases y que cada objeto
responda de una manera particular de acuerdo a su naturaleza. Así por ejemplo se puede
enviar el mensaje abrir a los objetos: candado, maletín, periódico y al objeto puerta y todos
ellos efectuarán una operación asociada a su naturaleza y se producirá una operación
diferente, para cada uno de ellos, a pesar de que la acción tiene el mismo nombre.
Dossier Programación III – Lic. Gladys Chuquimia Página 4
1.3.9. Función amiga.
Son aquellas funciones que han sido declaradas por la clase como amigas y que no son parte
activa de la clase pero por su característica pueden trabajar con todos los datos y métodos de
la clase de manera directa.
Se tienen en el mercado una diversidad de lenguajes de programación orientado a objetos. El
primer lenguaje de POO fue el SIMULA que emergió en el año 1964 y se deriva del ALGOL 60,
donde tiene sus raíces, del cual toma el concepto de bloque e introduce el concepto de objeto.
Luego se tiene al Smalltalk creado por Alan Kay que ha sido el inspirador de un gran número de
lenguajes OO, entre los cuales se mencionan al Eiffel y al C++.
Entre los programas más destacados OO que se emplean en la actualidad se mencionan al
lenguaje C++, Delphi, JAVA, Object Cobol, Prolog++ y el Smalltalk.
Ejercicio Propuesto.
Realice un mapa mental que explique ¿Qué es la programación orientada a objetos?
Identificando sus componentes.
Dossier Programación III – Lic. Gladys Chuquimia Página 5
Unidad II
Principios de la Programación Orientada a Objetos con Java
2.1. Introducción.
En esta unidad se cubren los aspectos centrales que son fundamentales para trabajar con
objetos, y diseñar un programa orientado a objetos en lenguaje Java.
Java fue diseñado en 1990 por James Gosling, de Sun Microsystems, como software para
dispositivos electrónicos de consumo. Curiosamente, todo este lenguaje fue diseñado antes de
que diese comienzo la era World Wide Web, puesto que fue diseñado para dispositivos
electrónicos como calculadoras, microondas y la televisión interactiva.
Inicialmente Java se llamó Oak (roble en inglés), aunque tuvo que cambiar de denominación,
debido a que dicho nombre ya estaba registrado por otra empresa. Se dice este nombre se le
puso debido a la existencia de tal árbol en los alrededores del lugar de trabajo de los
promotores del lenguaje.
Bill Joy (cofundador de Sun y uno de los desarrolladores principales del sistema operativo Unix
de Berckley) juzgó que Internet podría llegar a ser el campo adecuado para disputar a
Microsoft su primacía en el terreno del software, y vio en Oak el instrumento idóneo para
llevar a cabo estos planes.Para poder presentarlo en sociedad se tuvo que modificar el nombre
de este lenguaje de programación y se tuvo que realizar una serie de modificaciones de diseño
para poderlo adaptar al propósito mencionado. Así Java fue presentado en sociedad en agosto
de 1995.
Algunas de las razones que llevaron a Bill Joy a pensar que Java podría llegar a ser rentable
son:
9 Java es un lenguaje orientado a objetos: Esto es lo que facilita abordar la resolución de
cualquier tipo de problema.
9 Es un lenguaje sencillo, aunque sin duda potente.
9 La ejecución del código Java es segura y fiable: Los programas no acceden
directamente a la memoria del ordenador, siendo imposible que un programa escrito
en Java pueda acceder a los recursos del ordenador sin que esta operación le sea
permitida de forma explícita. De este modo, los datos del usuario quedan a salvo de la
existencia de virus escritos en Java. La ejecución segura y controlada del código Java es
una característica única, que no puede encontrarse en ninguna otra tecnología.
Dossier Programación III – Lic. Gladys Chuquimia Página 6
9 Es totalmente multiplataforma: Es un lenguaje sencillo, por lo que el entorno necesario
para su ejecución es de pequeño tamaño y puede adaptarse incluso al interior de un
navegador.
Las clases son abstracciones que representan a un conjunto de objetos con un
comportamiento e interfaz común.
Se define a una clase como: "un conjunto de cosas (físicas o abstractas) que tienen el mismo
comportamiento y características... Es la implementación de un tipo de objeto (considerando
los objetos como instancias de las clases)".
Una clase no es más que una plantilla para la creación de objetos. Cuando se crea un objeto
(instanciación) se ha de especificar de qué clase es el objeto instanciado, para que el
compilador comprenda las características del objeto.
Las clases presentan el estado de los objetos a los que representan mediante variables
denominadas atributos. Cuando se instancia un objeto el compilador crea en la memoria
dinámica un espacio para tantas variables como atributos tenga la clase a la que pertenece el
objeto.
Los métodos son las funciones mediante las que las clases representan el comportamiento de
los objetos. En dichos métodos se modifican los valores de los atributos del objeto, y
representan las capacidades del objeto (también se les denomina servicios).
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 fuente con la siguiente sintaxis:
public class NombreDeLaClase{
//Atributos
//Métodos
}
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, el nombre del archivo que guarda la clase es:
NombreDeLaClase.java. También se resalta que Java diferencia entre mayúsculas y
minúsculas; por tanto, el nombre de la clase y el de archivo fuente han de ser exactamente
iguales.
Ejemplo de la creación de una clase
public class Circulo{
private double x, y; // las coordenadas del centro
public double r; // el radio
// métodos que retornan la circunferencia y el área de circulo.
Dossier Programación III – Lic. Gladys Chuquimia Página 7
public double area() {return 3.14159 * r * r;}
}
El control de acceso a los métodos está determinado por las palabras reservadas:
9 private
9 private protected
9 protected
9 public
Veamos la siguiente tabla:
Prívate X
private protected X X
protected X X X
Public X X X X
Las X habilitan desde donde se tienen acceso a los miembros dato de la clase.
De esta manera si los miembros de la clase son declarados de tipo private, sólo la clase que
contiene al método puede llamarlo. Ahora bien, si se declaran como private protected,
permite acceso a la clase y a cualquier subclase de la clase que quiera invocar al método. Si los
miembros son declarados como protected, brinda acceso solo a los miembros de la clase, las
subclases y todas las clases contenidas en el mismo paquete. Finalmente si son declarados de
tipo public, todas las clases tienen acceso.
Los objetos del mundo real comparten dos características: Todos tienen estado y
comportamiento. Los perros tienen estado (nombre, color, raza, hambriento) y
comportamiento (ladrando, buscando, meneando la cola). Las bicicletas también tienen un
estado (marcha actual, cadencia de pedaleo actual, velocidad actual) y comportamiento
(cambio de marcha, cambio de cadencia de pedaleo, frenar). Identificar el estado y el
comportamiento de los objetos del mundo real es una gran ayuda para empezar a pensar en
términos de programación orientada a objetos, lo que se toma en cuenta en Java.
Los objetos siempre son la instancia de una clase y utilizan memoria dinámica. Al crear un
objeto se reserva espacio en memoria para sus variables a través de new (empleado en la
definición de objeto) y se devuelve una referencia al objeto. La Sintaxis para declarar un objeto
simple, es:
NombreDeLaClase nombreObjeto = new NombreDeLaClase();
Dossier Programación III – Lic. Gladys Chuquimia Página 8
Se envía mensaje a través de los objetos, cuya sintaxis es la siguiente:
Objeto.Metodo()
Objeto.Atributo
Tanto el método invocado como el atributo deben tener acceso público o tener los derechos
para manipular estos miembros de la clase.
2.6. Constructores.
Un constructor es un elemento de una clase cuyo identificador coincide con el de la clase
correspondiente y que tiene por objetivo obligar a y controlar cómo se inicializa una instancia
de una determinada clase, ya que el lenguaje Java no permite que las variables miembro de
una nueva instancia queden sin inicializar. Además, a diferencia de los métodos, los
constructores sólo se ejecutan cuando se declara un objeto, por única vez.
Así, un constructor es una función que sirve para construir un nuevo objeto y asignar valores a
sus miembros dato. Se caracteriza por:
9 Tener el mismo nombre que la clase
9 No devuelven valores
9 Pueden tener argumentos
9 Pueden existir más de un constructor para una clase
Los constructores se declaran en el momento de definir la clase:
public class A {
int x, y;
public A() { x=0; y=0; } // el constructor
}
El constructor puede tener argumentos. En este caso, se deben colocar los argumentos
respectivos al crear el objeto:
public class A {
int x, y;
public A(int ix, int iy)
{ x=ix; y=iy; } // el constructor
…
}
Se pueden colocar varios constructores. Durante la creación de un objeto, se invoca aquel
constructor que coincide totalmente con los argumentos dados:
public class A {
int x, y;
public A() { x=0; y= 0; }
public A(int ix, int iy)
Dossier Programación III – Lic. Gladys Chuquimia Página 9
{ x=ix; y=iy; }
public A(A from)
{ x= from.x; y= from.y; }
}
Luego, las llamadas serían:
A a1= new A(); //Es ejecutado el constructor sin argumentos previamente declarado.
A a2= new A(1,2); //Se ejecuta el constructor con dos argumentos.
A a3= new A(a2); //Ejecución del constructor con un argumento.
2.7. Destructor.
Un destructor es un método que se invoca automáticamente cuando el objeto se destruye.
JAVA no posee destructores, porque tiene recolección de basuras. Un destructor es un método
que es ejecutado cada vez que se destruye (se elimina de RAM) un objeto, el objetivo de este
método es el de eliminar toda la memoria que ocupó un objeto. En JAVA no es necesaria la
definición de destructores, pues el mismo lenguaje se encarga de la eliminación y liberación de
la memoria ocupada por un objeto, esto se realiza cada vez que un objeto pierde todas sus
referencias.
En resumen es un método de clase que sirve para realizar ciertas operaciones necesarias al
dejar de existir un objeto, por ejemplo, cerrar conexiones de una comunicación, cerrar
ficheros, etc.
Java dispone de un elemento denominado recolector de basura (garbage collector) que se
encarga de liberar memoria asignada a objetos que ya no se utilizan, aún así en ocasiones será
necesario disponer de una función que realice operaciones adicionales a la mera liberación de
memoria. Para este fin se crea un método, denominado finalize, con las siguientes
características:
protected void finalize()
{
… cuerpo del destructor
}
Los objetos son variables y tienen las mismas capacidades y atributos que cualquier tipo de
variables, por tanto es posible disponer objetos en un array. La sintaxis es exactamente igual a
la utilizada para declarar y acceder al array. También disponemos de arrays bidimensionales.
Declaración:
NombreClase nombreObjeto[ ] = new NombreClase[20];
Dossier Programación III – Lic. Gladys Chuquimia Página 10
Inicialización:
nombreObjeto[posición] = new NombreClase( );
Ejercicios Propuestos
1. Implementación la clase Dibujo, que muestre el dibujo que desee diseñar.
2. Implemente completamente la clase Pila.
3. Diseñe la clase círculo.
4. Elabore la clase matriz; que efectúe las operaciones principales y la generación de al
menos dos matrices especiales.
5. Diseñe la clase vector, que realice las operaciones fundamentales que se desarrollan
con vectores, además de incluir métodos de búsqueda y ordenación de vectores.
Dossier Programación III – Lic. Gladys Chuquimia Página 11
Unidad III
Sobrecarga
La capacidad de realizar una acción diferente sin cambiar el nombre del método o el símbolo
del operador, según la naturaleza del objeto.
El lenguaje Java pone a nuestra disposición todas las herramientas necesarias que permiten
efectuar la sobrecarga de funciones y nos dan en forma implícita la sobrecarga de operadores,
que se considera en esta unidad.
A través de esta propiedad dos o más funciones pueden tener el mismo nombre representado
cada cual con un código diferente, que incide en la ejecución del método implementado; y es a
la capacidad de realizar diferentes acciones bajo un mismo denominativo que se la conoce
como sobrecarga de funciones.
Una función sobrecargada se distingue básicamente por los siguientes aspectos:
• Tienen más de una definición para el mismo nombre de función.
• Cada definición difiere en el número de argumentos.
• Sus argumentos pueden contemplar diferentes tipos de datos.
En Java se pueden sobrecargar todas las funciones que se definan, siguiendo las reglas
mencionadas.
La sobrecarga de funciones sigue la siguiente sintaxis:
public class NombreDeLaClase{
// atributos
// Métodos
public TD MetodoSobrecargado() {
//Instrucciones
}
public TD MetodoSobrecargado(TD arg1) {
//Instrucciones
}
public TD MetodoSobrecargado(TD arg1, TD argN) {
//Instrucciones
}
}
Donde, TD representa a un tipo de dato válido, así porejemplo: int, float, etc ó void.
Dossier Programación III – Lic. Gladys Chuquimia Página 12
Así por ejemplo, consideremos este programa:
public class Encuentro
{
public void Saludo ()
{
System.out.println ();
System.out.println ("Hola Amig@");
}
public void Saludo (String nom)
{
System.out.println ("Hola " + nom);
}
public void Saludo (String palabra, String nom)
{
System.out.println (palabra + nom);
}
public static void main (String[] args)
{
Encuentro obj = new Encuentro ();
obj.Saludo ();
obj.Saludo ("Susana");
obj.Saludo ("Bienvenida ", "Anita");
}
}
En la clase encuentro se observa con claridad que el método Saludo está dos veces
sobrecargado, y que se ejecuta el mismo método de diferentes maneras según el parámetro
que se envíe desde el programa principal.
Finalmente se menciona que se consideró el proceso de sobrecarga cuando se efectúo la
declaración de más de un constructor, dado que bajo el nombre de la clase se define más de
una vez el constructor. Ejemplo:
public class Encuentro
{
public Encuentro ()
{
System.out.println ("Es un encuentro...");
}
public Encuentro (String nom)
{
Dossier Programación III – Lic. Gladys Chuquimia Página 13
System.out.println ("Es un encuentro con " + nom);
}
public void Saludo ()
{
System.out.println ();
System.out.println ("Hola Amig@s");
}
public void Saludo (String nom)
{
System.out.println ("Hola " + nom);
}
public void Saludo (String palabra, String nom)
{
System.out.println (palabra + nom);
}
public static void main (String[] args)
{
Encuentro obj1 = new Encuentro ();
obj1.Saludo ();
Encuentro obj2 = new Encuentro ("Susana");
obj2.Saludo ("Susana");
obj2.Saludo ("Que tal ", "Anita");
}
}
En Java prácticamente en forma explícita No existe. En los objetos String el operador + y += se
permiten para la comparación de cadenas.
El lenguaje Java sobrecarga la definición del operador + para incluir la concatenación de
cadenas. El siguiente ejemplo utiliza + para concatenar la cadena "Contados ", con el valor de
la variable contador y la cadena " caracteres.":
System.out.print("Contados" + contador + "caracteres.");
Dossier Programación III – Lic. Gladys Chuquimia Página 14
Esta operación automáticamente convierte el valor de contador a una cadena de caracteres,
efectuándose de esta manera la sobrecarga.
Ejercicios Propuestos
1. Diseña un programe que sobrecargue la función préstamo de la clase CuentaBancaria.
2. Implemente la clase matriz que sobrecargue la función de cargado de datos a la matriz,
luego, efectúe la sobrecarga de constructor correspondiente.
Dossier Programación III – Lic. Gladys Chuquimia Página 15
Unidad IV
Herencia
4.1. Herencia.
La verdadera potencia de la programación orientada a objetos radica en su
capacidad para reflejar la abstracción que el cerebro humano realiza
automáticamente durante el proceso de aprendizaje y el proceso de análisis de
información.
Es así que las personas percibimos la realidad como un conjunto de objetos
interrelacionados. Dichas interrelaciones, pueden verse como un conjunto de
abstracciones y generalizaciones que se han ido asimilando desde la niñez. Por
eso se afirma que esta técnica se adecua mejor al funcionamiento del cerebro
humano, al permitir descomponer un problema de cierta magnitud en un
conjunto de problemas menores subordinados del primero.
La capacidad de descomponer un problema o concepto en un conjunto de objetos
relacionados entre sí, y cuyo comportamiento es fácilmente identificable, es muy
útil en el desarrollo de programas informáticos.
4.2. Jerarquía
La herencia es el mecanismo fundamental de relación entre clases en la orientación a objetos.
Relaciona las clases de manera jerárquica; una clase padre, base o superclase sobre otras
clases hijas, derivadas o subclases.
Padre
Hija1 Hija 2
Hija 1.1 Hija 1.2
Hija 1.1.1.
La herencia simple se realiza tomando una clase existente y derivando nuevas clases de ella
tan solo una vez.
Dossier Programación III – Lic. Gladys Chuquimia Página 16
En la herencia simple los descendientes de una clase heredan todas las variables y métodos
que sus ascendientes hayan especificado como heredables, además de crear los suyos propios.
La característica de herencia, nos permite definir nuevas clases derivadas de otra ya existente,
que la especializan de alguna manera. Así logramos definir una jerarquía de clases, que se
puede mostrar mediante la jerarquización.
En todo lenguaje orientado a objetos existe una jerarquía, mediante la que las clases se
relacionan en términos de herencia. En Java, el punto más alto de la jerarquía es la clase
Object de la cual derivan todas las demás clases.
Esquemáticamente se la representa así:
Clase Padre
Clase Hija1 Clase Hija N
Los constructores y destructores de la clase base no se heredan por clases derivadas. En su
lugar, los constructores de las clases hijas deben contener información de parámetros de los
constructores de la clase base. La llamada a un constructor de una clase base se hace del
mismo modo que las llamadas a los constructores de los miembros objeto. Se ejecutan los
constructores definidos en la Clase Padre y luego de las hijas en orden de jerarquía, y en
cuanto al destructor se ejecuta en forma inversa.
4.5. Applets.
La clase Applet Java, de la cual han de heredar todos los programas Java que vayan a actuar
como applets, es la única clase que contiene el paquete java.applet de la API de Java.
Esta clase hereda de Object (como todas las clases Java), pero además hereda de Component y
Container, que son dos clases del paquete gráfico AWT. Esto ya perfila las posibilidades
gráficas de este tipo de aplicaciones Java.
El ciclo de vida de un applet no es tan sencillo como el de una aplicación, que simplemente se
ejecuta hasta que finaliza su método main(). La siguiente figura modeliza el ciclo de vida de
una applet:
Dossier Programación III – Lic. Gladys Chuquimia Página 17
Cada círculo representa una fase en el ciclo de vida de la applet. Las flechas representan
transiciones y el texto representa la acción que causa la transición. Cada fase está marcada con
una invocación a un método de la applet:
void init(); Es invocado cuando se carga la applet. Aquí se suelen introducir las iniciaciones que
la applet necesite.
void start();Es invocado cuando la applet, después de haber sido cargada, ha sido parada
(cambio de página Web, minimización del navegador,...), y de nuevo activada (vuelta a la
página, restauración del navegador,...). Se informa a la applet de que tiene que empezar su
funcionamiento.
void stop(); Es invocado para informar a la applet de que debe de parar su ejecución. Así una
applet que utilice threads, debería detenerlos en el código de este método.
void destroy();Es invocado para informar a la applet de que su espacio está siendo solicitado
por el sistema, es decir el usuario abandona el navegador. La applet debe de aprovechar este
momento para liberar o destruir los recursos que está utilizando.
void paint(); Es invocado cada vez que hay que el navegador redibuja la applet.
Al crear una applet no es necesario implementar todos estos métodos. De hecho habrá applets
que no los necesiten.
Cuando un navegador carga una página Web que contiene una applet, suele mostrar en su
parte inferior un mensaje como:
initializing... starting...
Esto indica que la applet, se está cargando:
1. Una instancia de la clase applet es creada.
2. La applet es iniciada, mediante su método init().
3. La applet empieza a ejecutarse, mediante su método start().
Cuando el usuario se encuentra con una página Web, que contiene una applet y salta a otra
página, entonces la applet se detiene invocando a su método stop(). Si el usuario retorna a la
Dossier Programación III – Lic. Gladys Chuquimia Página 18
página donde reside la applet, ésta vuelve a ejecutarse nuevamente invocando a su método
start().
Cuando el usuario sale del navegador la applet tiene un tiempo para finalizar su ejecución y
hacer una limpieza final, mediante el método destroy().
Para incluir una applet en una página Web, una vez compilada la applet, debe incluirse entre el
código HTML de la página Web una etiqueta <APPLET>, que como mínimo ha de presentar los
siguientes tres parámetros:
code: Especifica el URL del fichero de clase Java (*.class) que contiene la applet.
width: Especifica la anchura inicial de la applet (en pixels).
heigth: Especifica la altura inicial de la applet (en pixels).
Así por ejemplo:
<applet code="AppletDiagonal.class" width=200 height=200>
</applet>
En la orientación a objetos, se consideran dos tipos de herencia, simple y múltiple. En el caso
de la primera, una clase sólo puede derivar de una única superclase. Para el segundo tipo, una
clase puede descender de varias superclases. En Java se trabaja con una Herencia Múltiple
indirecta y con Interfases.
Para indicar que una clase deriva de otra, heredando sus propiedades (métodos y
atributos), se usa el término extends, como en el siguiente ejemplo:
public class SubClase extends SuperClase {
// Contenido de la clase
}
Por ejemplo, creamos una clase MiPunto3D, hija de la clase MiPunto:
//Clase Padre o Superclase
public class MiPunto{
int x, y;
//Metodos
}
Dossier Programación III – Lic. Gladys Chuquimia Página 19
//Clase Hija o SubClase
public class MiPunto3D extends MiPunto {
int z;
MiPunto3D( ) {
x = 0; // Heredado de MiPunto
y = 0; // Heredado de MiPunto
z = 0; // Nuevo atributo
}
}
La palabra clave extends se utiliza para decir que deseamos crear una subclase de la clase que
es nombrada a continuación, en este caso MiPunto3D es hija de MiPunto.
Todos los campos y métodos de una clase son siempre accesibles para el código de la misma
clase. Para controlar el acceso desde otras clases, y para controlar la herencia por las subclase,
los miembros (atributos y métodos) de las clases tienen tres modificadores posibles decontrol
de acceso:
public: Los miembros declarados public son accesibles en cualquier lugar en que sea accesible
la clase, y son heredados por las subclases.
private: Los miembros declarados prívate son accesibles sólo en la propia clase.
protected: Los miembros declarados protectedson accesibles sólo para sus subclases
Por ejemplo:
public class Padre
{ // Hereda de Object
// Atributos
private int numeroFavorito, nacidoHace, dineroDisponible;
// Métodos
public int getApuesta ()
{
return numeroFavorito;
}
protected int getEdad ()
{
Dossier Programación III – Lic. Gladys Chuquimia Página 20
return nacidoHace;
}
private int getSaldo ()
{
return dineroDisponible;
}
}
public class Hija extends Padre
{
// Definición
}
En este ejemplo, un objeto de la clase Hija, hereda los tres atributos (numeroFavorito,
nacidoHace y dineroDisponible) y los dos métodos (getApuesta() y getEdad() ) de la clase
padre, y podrá invocarlos. Cuando se llame al método getEdad() de un objeto de la clase Hija,
se devolverá el valor de la variable de instancia nacidoHace de ese objeto, y no de uno de la
clase padre.
Sin embargo, un objeto de la clase hija, no podrá invocar al método getSaldo() de un objeto de
la clase padre, con lo que se evita que el hijo conozca el estado de la cuenta corriente de un
padre.
Ejercicios Propuestos
1. Represente la clase Animal mediante las relaciones de herencia, cree al menos dos
clases derivadas.
2. Implemente la clase Teatro e incluya la representación de herencia múltiple.
3. Diseñe un programa en el que incluya relaciones de herencia, y constructores para
representar a los arreglos.
Dossier Programación III – Lic. Gladys Chuquimia Página 21
Unidad V
Funciones Virtuales y Polimorfismo
5.1. Introducción.
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 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 referido 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.
5.2. Ligadura.
Existen dos tipos de ligadura: Estática y dinámica.
La ligadura estática (o temprana), consiste en realizar el proceso de ligadura en tiempo de
compilación según el tipo declarado del objeto al que se manda el mensaje. La utilizan (en
Java) los métodos de clase y los métodos de instancia que son privados o final (ya que estos
últimos no pueden ser sobrescritos).
En tanto que, la ligadura dinámica (o tardía), consiste en realizar el proceso de ligadura en
tiempo de ejecución siendo la forma dinámica del objeto la que determina la versión del
método a ejecutar. Se utiliza en todos los métodos de instancia de Java que no son privados ni
final. Sirve para resolver conflictos entre Superclases y Subclases, cuando existe un conflicto
entre un método de una superclase y un método de la subclase, el comportamiento correcto
es que el método de la subclase sobrescriba al de la superclase.
También significa que la forma dinámica del objeto determina la versión de la operación que
se aplicara. Esta capacidad de las operaciones para adaptarse automáticamente a los objetos a
los cuales se aplican es una de las propiedades más importantes de la orientación a objetos.
Aunque puede variar de un lenguaje a otro, se presentan unas características comunes. Así, los
métodos que necesitan ligadura dinámica son aquellos que pueden ser redefinidos. Por
ejemplo, en Java, los métodos de clase y los métodos de instancia privados y/o finales no
Dossier Programación III – Lic. Gladys Chuquimia Página 22
presentan ligadura dinámica. En Java, si no se especifica nada se entenderá que el método
puede ser redefinido y por tanto debe presentar ligadura dinámica.
Una función virtual es miembro de una clase que se declara dentro de una clase base y se
redefine en una clase derivada. Para crear una función virtual hay que preceder a la
declaración de la función la palabra clave virtual. Debe tener el mismo tipo y numero de
parámetros y devolver el mismo tipo.
Cada redefinición de la función virtual en una clase derivada expresa el funcionamiento
especifico de la misma con respecto a esa clase derivada. Cuando se redefine una función
virtual en una clase derivada NO es necesaria la palabra virtual.
5.4. Polimorfismo.
El polimorfismo es el uso de la misma definicion con diferentes tipos de datos, sobrecarga de
operadores (ingl. operator overloading).
En el siguiente ejemplo en el cual se crean cuatro programas se puede observar el
polimorfismo:
public abstract class Animal
{
public abstract void come ();
}
public class Lobo extends Animal
{
public void come ()
{
System.out.println ("¡Yo como como un lobo!\n");
}
}
public class Pez extends Animal
{
public void come ()
{
System.out.println ("¡Yo como como un pez!\n");
}
}
public class EjecutaEjemploHerenciaAnimalLoboPez
{
public static void main (String[] args)
{
Dossier Programación III – Lic. Gladys Chuquimia Página 23
Lobo unLobo = new Lobo ();
Pez unPez = new Pez ();
unLobo.come ();
unPez.come ();
}
}
5.5. Clases Abstractas
Hay ocasiones, cuando se desarrolla una jerarquía de clases en que algún comportamiento
está presente en todas ellas pero se materializa de forma distinta para cada una. Por ejemplo,
pensemos en una estructura de clases para manipular figuras geométricas. Podríamos pensar
en tener una clase genérica, que podría llamarse FiguraGeometrica y una serie de clases que
extienden a la anterior que podrían ser Circulo, Poligono, etc. Podría haber un método dibujar
dado que sobre todas las figuras puede llevarse a cabo esta acción, pero las operaciones
concretas para llevarla a cabo dependen del tipo de figura en concreto (de su clase). Por otra
parte la acción dibujar no tiene sentido para la clase genérica FiguraGeometrica, porque esta
clase representa una abstracción del conjunto de figuras posibles.
Para resolver esta problemática Java proporciona las clases y métodos abstractos. Un método
abstracto es un método declarado en una clase para el cual esa clase no proporciona la
implementación (el código). Una clase abstracta es una clase que tiene al menos un método
abstracto. Una clase que extiende a una clase abstracta debe implementar los métodos
abstractos (escribir el código) o bien volverlos a declarar como abstractos, con lo que ella
misma se convierte también en clase abstracta.
Declaración e implementación de métodos abstractos
Una clase abstracta y una función virtual se definen:
abstract class FiguraGeometrica {
abstract void dibujar();
}
class Circulo extends FiguraGeometrica {
void dibujar() {
// codigo para dibujar Circulo
}
}
La clase abstracta se declara simplemente con el modificador abstract en su declaración. Los
métodos abstractos se declaran también con el mismo modificador, declarando el método
pero sin implementarlo (sin el bloque de código encerrado entre {}). La clase derivada se
declara e implementa de forma normal, como cualquier otra. Sin embargo si no declara e
Dossier Programación III – Lic. Gladys Chuquimia Página 24
implementa los métodos abstractos de la clase base (en el ejemplo el método dibujar) el
compilador genera un error indicando que no se han implementado todos los métodos
abstractos y que, o bien, se implementan, o bien se declara la clase abstracta.
Referencias y objetos abstractos
Se pueden crear referencias a clases abstractas como cualquier otra. No hay ningún problema
en poner:
FiguraGeometrica figura;
Sin embargo una clase abstracta no se puede instanciar, es decir, no se pueden crear objetos
de una clase abstracta. El compilador producirá un error si se intenta:
FiguraGeometrica figura = new FiguraGeometrica();
Esto es coherente dado que una clase abstracta no tiene completa su implementación y encaja
bien con la idea de que algo abstracto no puede materializarse.
Sin embargo utilizando el up‐casting visto en el capítulo dedicado a la Herencia si se puede
escribir:
FiguraGeometrica figura = new Circulo(. . .);
figura.dibujar();
La invocación al método dibujarse resolverá en tiempo de ejecución y la JVM llamará al
método de la clase adecuada. En este ejemplo se llamará al método dibujar de la clase Círculo.
Ejercicios Propuestos
1. Implemente el polimorfismo en las clase Mueble, para el cual cree tres clases
derivadas.
2. En la clase base Animal y las clases derivadas: Mamifero y Oviparo implemente el
polimorfismo
Dossier Programación III – Lic. Gladys Chuquimia Página 25
Unidad VI
Plantillas y Tratamiento de Excepciones
6.1. Plantillas.
Una plantilla es una forma que suele proporcionar una separación entre la forma o estructura
y el contenido. Es un medio que permite guiar, portar o construir un diseño o esquema
predefinido.
Una plantilla agiliza el trabajo de reproducción de muchas copias idénticas o casi idénticas (que
no tiene que ser tan elaborado, sofisticado o personal). Si se quiere un trabajo más refinado,
más creativo, la plantilla no es sino un punto de partida, un ejemplo, una idea aproximada de
lo que se quiere hacer.
Desde luego la POO supuso un formidable avance del arsenal de herramientas de
programación. Se toman en cuenta que las manipulaciones contienen un denominador común
que se repite bajo apariencias diversas. Por ejemplo, la idea de ordenación "Sort" se repite
infinidad de veces en la programación, aunque los objetos a ordenar y los criterios de
ordenación varíen de un caso a otro. Alrededor de esta idea surgió un nuevo paradigma
denominado programación genérica o funcional.
La programación genérica está mucho más centrada en los algoritmos que en los datos y su
postulado fundamental puede sintetizarse en una palabra: generalización. Significa que, en la
medida de lo posible, los algoritmos deben ser parametrizados al máximo y expresados de la
forma más independiente posible de detalles concretos, permitiendo así que puedan servir
para la mayor variedad posible de tipos y estructuras de datos.
Los expertos consideran que la parametrización de algoritmos supone una aportación a las
técnicas de programación, al menos tan importante, como fue en su momento la introducción
del concepto de herencia, y que permite resolver algunos problemas que aquella deja sin
solución.
Luego, las plantillas se basan en la programación orientada al dato razona del siguiente modo:
representemos un tipo de dato genérico (por ejemplo int) que permita representar objetos
con ciertas características comunes (peras y manzanas). También se definen operaciones que
pueden aplicarse a este tipo (por ejemplo aritméticas) y sus reglas de uso,
independientemente que el tipo represente peras o manzanas en cada caso.
6.2. Excepciones.
En todo programa existen errores inesperados en tiempo de ejecución, y también errores que
no consideramos debido a nuestra propia inexperiencia como programadores. Unos de estos
errores ocurren por ejemplo, al intentar acceder a un elemento del arreglo que está fuera del
Dossier Programación III – Lic. Gladys Chuquimia Página 26
límite de nuestro arreglo, o cuando intentamos acceder a un archivo inexistente, entre otros.
Normalmente estos errores interrumpen el flujo de ejecución de nuestros programas, hasta el
extremo de provocar la terminación del programa en forma inmediata. Java hace uso de las
excepciones para poder controlar los errores en tiempo de ejecución. En Java, casi todo los
tipos de errores que puedan surgir en tiempo de ejecución lanzan excepciones, es decir,
cuando ocurre un error dentro de un método de Java, este método crea un objeto Exception,
dicho objeto contiene información sobre la excepción, que incluye su tipo y el estado del
programa cuando ocurrió el error. El sistema de ejecución es el responsable de buscar algún
código para manejar el error. El manejo de excepciones en Java sigue una estructura como
esta:
try {
//Codigo donde puede ocurrir un error
}
catch (ExcepcionA ex)
{ // Que se va a hacer en caso que se lanze una Excepcion A }
catch (ExcepcionZ ex)
{ // Que se va a hacer en caso que se lanze una Excepcion Z }
Dentro del bloque try{ } viene encerrado la parte del programa que se desea manejar sus
excepciones. El código dentro de algún catch (TipoExcepcion e) se ejecuta en caso se que lanze
una excepción TipoExcepcion o que pertenezca al grupo TipoExcepcion. El sistema de
ejecución Java busca hacia atrás en la pila de llamadas para encontrar el método que esté
interesado en manejar una excepción particular. Es decir si se lanza una excepción en el
método, pero si no está interesado en manejar dicha excepción, entonces el sistema de
ejecución Java ve quién lo llamó, entonces se regresa a y ve si está interesado en dicha
excepción, y así consecutivamente hasta llegar al método principal de nuestra aplicación. En
caso de no encontrar alguien que quiera manejarlo, comúnmente Java manda una lista de
mensajes en nuestra ventana de consola, y en muchos casos se termina la ejecución de
nuestro programa. Cuando manejamos excepciones, podemos manejar excepciones en forma
específica (por ejemplo, usar un índice que está fuera de los límites de nuestro arreglo), o
manejar una excepción de cierta categoría (por ejemplo, una excepción lanzada por mal uso de
un arreglo de datos), o manejar todas las excepciones en su conjunto. Para el primer caso, es
necesario este código catch(ArrayIndexOutOfBoundsException e){ }, para el segundo catch
(ArrayException e){} y para el último catch (Exception e){ }. En la práctica no es recomendable
hacer usar de manejadores de excepciones demasiado generales, como la del último caso. Las
excepciones son parte de Java, y es muy común usarlos en las operaciones E/S, ya que es
donde más probabilidad hay de que se lance una.
Dossier Programación III – Lic. Gladys Chuquimia Página 27
6.3. Lanzamiento de Excepciones.
Todos los métodos Java utilizan la sentencia throw para lanzar una excepción. Esta sentencia
requiere un sólo argumento (un objeto Throwable). Si vemos el siguiente código de la función
pop() cuyo propósito es sacar el elemento superior de la pila.
public Object pop() throws EmptyStackException {
Object obj;
if (size == 0)
throw new EmptyStackException();
obj = objectAt(size ‐ 1);
setObjectAt(size ‐ 1, null);
size‐‐;
return obj;
}
El método pop() comprueba si la pila no está vacía. Si lo está, crea un nuevo objeto de la clase
EmptyStackException y lo lanza, aunque en el método no se genere alguna excepción debido a
lo bien validado que se encuentra, nosotros somos quienes lo lanzamos. Además por lógica, la
clase EmpyStackException es una subclase de Thowable, ya que en cualquier otro caso, no se
podría lanzar dicha excepción. Algo que se debe considerar aquí, es que en la declaración del
procedimiento añade el siguiente código throws EmptyStackException, throws es una palabra
reservada de java, y EmpyStackException es una subclase de Throwable. El uso de throws
permite evitarnos la molestia de capturar las excepciones del tipo de excepciones indicadas
después de esta palabra (las clases van separadas por coma), esto debido a que deja al sistema
de ejecución Java que decida cuál sería la mejor opción en caso de que ocurriera una
excepción de los tipos indicados.
Ejercicios Propuestos
1. Implemente la clase Listas para que trabaje con distintos tipos de elementos.
2. Diseñe la clase Colas completamente para que sea genérica y trabaje con diferentes
tipos de datos.
Dossier Programación III – Lic. Gladys Chuquimia Página 28