Beruflich Dokumente
Kultur Dokumente
Polimorfismo y excepciones
4.1 Definicin de polimorfismo
Polimorfismo
El polimorfismo es un concepto de la programacin orientada a objetos que nos permite programar en forma
general, en lugar de hacerlo en forma especfica. En general nos sirve para programar objetos con
caractersticas comunes y que todos estos compartan la misma superclase en una jerarqua de clases, como si
todas fueran objetos de la superclase. Esto nos simplifica la programacin.
Para ponerlo en prctica se har un ejemplo bastante sencillo. Se har una librera de clases que represente
figuras tridimensionales y bidimensionales, y su respectiva jerarqua de clases. Las clases deben ser capaces
de tener funcionamiento bastante bsico, como obtener reas, volmenes y permetros de la figura
correspondiente.
La representacin de la jerarqua sera como sta:
La superclase de dicha jerarqua podra ser muy parecida a sta:
public abstract class figura {
protected String nombre;
protected int color;
protected int grosorBorde;
public String getNombre(){
return this.nombre;
}
public void setNombre(String n){
this.nombre=n;
}
public int getColor(){
return this.color;
}
public void setColor(int c){
this.color=c;
}
public int getGrosorBorde(){
return this.grosorBorde;
}
public void setGrosorBorde(int g){
this.grosorBorde=g;
}
public abstract void dibujar();
}
Las siguientes clases en el nivel de la jerarqua podran quedar muy parecidas a stas:
crculos y rectngulos, sino tambin para cualquier otra figura derivada de la clase base Figura. As si se
deriva Triangulo de Figura, y se aade a la jerarqua de clases, la funcin figuraMayor podr manejar objetos
de dicha clase, sin modificar para nada el cdigo de la misma.
Veamos ahora la llamada a la funcin figuraMayor
Figura[] fig=new Figura[4];
fig[0]=new Rectangulo(0,0, 5.0, 7.0);
fig[1]=new Circulo(0,0, 5.0);
fig[2]=new Circulo(0, 0, 7.0);
fig[3]=new Rectangulo(0,0, 4.0, 6.0);
Figura fMayor=figuraMayor(fig);
System.out.println("El rea mayor es "+fMayor.area());
Pasamos el array fig a la funcin figuraMayor, el valor que retorna lo guardamos en fMayor. Para conocer el
valor del rea, desde fMayor se llamar a la funcin miembro area. Se llamar a la versin correcta
dependiendo de la referencia al tipo de objeto que guarde por fMayor. Si fMayor guarda una referencia a un
objeto de la clase Circulo, llamar a la funcin area definida en dicha clase. Si fMayor guarda una referencia
a un objeto de la clase Rectangulo, llamar a la funcin area definida en dicha clase, y as sucesivamente.
La combinacin de herencia y enlace dinmico se denomina polimorfismo. El polimorfismo es, por tanto, la
tcnica que permite pasar un objeto de una clase derivada a funciones que conocen el objeto solamente por su
clase base.
El poder manipular un Objeto como si ste fuera de un tipo genrico otorga mayor flexibilidad al momento de
programar con Objetos, el trmino Polimorfismo tambin es asociado con un concepto llamado Late-Binding
(Ligamiento Tardo), observe el siguiente fragmento de cdigo:
Figura a = new Circulo();
Figura b = new Triangulo();
Inicialmente se puede pensar que este cdigo generara un error debido a que el tipo de referencia es distinta a
la instancia del objeto, sin embargo, el fragmento anterior es correcto y demuestra el concepto de
Polimorfismo; para asentar este tema se describe un ejemplo ms completo:
Uso de Polimorfismo.
El uso de Polimorfismo posee ciertos detalles que no fueron descritos en el ejemplo anterior, uno de estos, que
tambin tiene implicaciones en otros componentes es: Casting.
Uso de "Casting"
El termino "Casting" viene de la palabra "Cast" que significa Molde, por lo que el termino literal es Hacer un
Molde, en Polimorfismo se lleva acabo este proceso de "Casting" implcitamente, una Guitarra se coloca en
el molde de un Instrumento, un Triangulo en el molde de una Figura, sin embargo, en ciertas ocasiones se
requiere realizar un tipo de "Casting" que no es considerado seguro en trminos computacionales.
Anteriormente se mencion que el "Casting" llevado acabo con Polimorfismo es implcito, esto se debe a que
no se requiere de sintaxis especial, simplemente se convierte una Guitarra a un Instrumento, sin embargo,
para llevar una transformacin en sentido opuesto se requiere de sintaxis adicional para mantener la seguridad
de transformacin; analicemos: mientras se puede asegurar que un Triangulo es una Figura ("Up-Casting"),
una Figura no necesariamente es un Triangulo, claro esta que lo puede ser, pero en Java se requiere definir
explcitamente esta operacin ("Down-Casting").
El polimorfismo es una de las cualidades de ms dificil comprensin de la POO. Una de las ventajas de estos
lenguajes es su flexibilidad y el polimorfismo una de las herramientas que potencian esta cualidad. El
polimorfismo tiene un uso muy grfico cuando hacemos uso de la herencia.
El polimorfismo consiste en que toda referencia a un objeto de una clase especfica puede tomar la forma de
una referencia a un objeto de una clase heredada a la suya.
Con el polimorfismo (sig. Varias formas) se consigue que las instancias de una clase padre puedan hacer uso
de las funcionalidades de la clases hijas: misma instancia que se comporta de varias (poli) maneras
(morfismo).
Ejemplo:
Public class Animal(){
public void habla(){
System.out.println("No se que soy");
}
}
Public class Perro() extends Animal{
public void() habla(){
System.out.println("Guau");
}
}
Public class Gato() extends Animal{
public void() habla(){
System.out.println("Miau");
}
}
Public class Zoo(){
public static void main(String[] args) {
Animal animal = new Gato(); animal. Habla(); animal=new Perro(); animal. Habla();
}
}
El resultado por consola sera:
"Miau"
"Guau"
Definicin de excepciones
El trmino excepcin es un forma corta da la frase suceso excepcional y puede definirse de la siguiente
forma.
Una excepcin es un evento que ocurre durante la ejecucin del programa que interrumpe el flujo normal de
las sentencias.
Muchas clases de errores pueden utilizar excepciones desde serios problemas de hardware, como la avera de
un disco duro, a los simples errores de programacin, como tratar de acceder a un elemento de un array fuera
de sus lmites. Cuando dicho error ocurre dentro de un mtodo Java, el mtodo crea un objeto exception y lo
maneja fuera, en el sistema de ejecucin. Este objeto contiene informacin sobre la excepcin, incluyendo su
tipo y el estado del programa cuando ocurri el error. El sistema de ejecucin es el responsable de buscar
algn cdigo para manejar el error. En terminologa java, crear una objeto exception y manejarlo por el
sistema de ejecucin se llama lanzar una excepcin.
Hay ocasiones, cuando se desarrolla una jerarqua de clases en que algn 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 geomtricas. Podramos pensar en tener una clase genrica, que podra llamarse
FiguraGeometrica y una serie de clases que extienden a la anterior que podran ser Circulo, Poligono, etc.
Podra haber un mtodo dibujar dado que sobre todas las figuras puede llevarse a cabo esta accin, pero las
operaciones concretas para llevarla a cabo dependen del tipo de figura en concreto (de su clase). Por otra parte
la accin dibujar no tiene sentido para la clase genrica FiguraGeometrica, porque esta clase representa una
abstraccin del conjunto de figuras posibles.
Para resolver esta problemtica Java proporciona las clases y mtodos abstractos. Un mtodo abstracto es un
mtodo declarado en una clase para el cual esa clase no proporciona la implementacin (el cdigo). Una clase
abstracta es una clase que tiene al menos un mtodo abstracto. Una clase que extiende a una clase abstracta
debe implementar los mtodos abstractos (escribir el cdigo) o bien volverlos a declarar como abstractos, con
lo que ella misma se convierte tambin en clase abstracta.
min=0;
hor=0;
h = new Horas();
m = new Minutos();
s = new Segundos();
cadena = new String("0 : 0 : 0");
}
public String avanzar(){
seg = s.forward();
if(seg==0){
min=m.forward();
if(min==0){
hor=h.forward();
}
}
cadena = hor + " : " + min + " : " + seg;
return cadena;
}
public String reset(){
seg = s.reset();
min = m.reset();
hor = h.reset();
cadena = hor + " : " + min + " : " + seg;
return cadena;
}
}
Nuestra clase Cronometro est compuesta entre otras cosas por objetos del tipo Horas, Minutos y Segundos y
a travs del constructor de nuestra clase creamos las instancias de cada una de ellas.
Herencia
En java aunque no establezcamos de manera explcita la herencia siempre est presente, ya que todas las
clases que creemos heredan de la clase Object, por eso es vlido decir que en java todo es un objeto. La
sintaxis para la composicin es obvia pero, para realizar la herencia, hay una forma claramente distinta.
Cuando heredamos, estamos diciendo "Esta nueva clase es como esa clase antigua", por ejemplo es decir que
la clase Horas es una UnidadDeTiempo. Afirmamos esto en el cdigo dando el nombre de la clase como
siempre pero, antes de la apertura del lmite cuerpo de clase, pondremos la palabra clave "extends" seguida
por el nombre de la clase base. Cuando hagamos esto, obtendremos automticamente todos los datos
miembros
y
mtodos
de
la
clase
base.
La composicin y la herencia
Tanto la composicin como la herencia permiten poner sub-objetos dentro de tu nueva clase. Podramos
preguntarnos cul es la diferencia entre los dos, y cundo elegir uno en lugar del otro. La composicin es
generalmente usada cuando deseamos las caractersticas de una clase existente dentro de una nueva clase,
pero no su interfaz. Es decir, ponemos un para poder usarlo para implementar caractersticas de nuestra nueva
clase, pero el usuario de esa nueva clase ver el interfaz que hemos definido en lugar del interfaz del objeto
insertado.
Los objetos miembros usan la implementacin ocultndose a s mismos, por lo que esto es una cosa segura a
hacer y, cuando el usuario sabe que estamos uniendo un conjunto de partes, hace que el interfaz sea ms fcil
de entender.
Cuando heredamos, estamos cogiendo una clase existente y creando una versin especial de esa clase. En
general, esto significa que estamos tomando una clase de propsito general, especializndola para un caso o
necesidad particular. Pensando un poco, podr entender que no tendra sentido construir un coche usando un
objeto vehculo (un coche no contiene un vehculo, es un vehculo!). La relacin es- un viene expresada por
la herencia, y la relacin tiene un viene expresada por la composicin.
Error: Excepciones que indican problemas muy graves, que suelen ser no recuperables y no deben
casi nunca ser capturadas.
Exception: Excepciones no definitivas, pero que se detectan fuera del tiempo de ejecucin.
Todas las excepciones tienen como clase base la clase Throwable, que est incluida en el paquete java.lang, y
sus mtodos son:
La idea general es que cuando un objeto encuentra una condicin que no sabe manejar crea y dispara una
excepcin que deber ser capturada por el que le llam o por alguien ms arriba en la pila de llamadas. Las
excepciones son objetos que contienen informacin del error que se ha producido y que heredan de la clase
Throwable o de la clase Exception. Si nadie captura la excepcin interviene un manejador por defecto que
normalmente imprime informacin que ayuda a encontrar quin produjo la excepcin.
Existen dos categoras de excepciones:
Excepciones verificadas: El compilador obliga a verificarlas. Son todas las que son lanzadas
explicitamente por objetos de usuario.
Generacion de exepciones
Supongamos que tenemos una clase Empresa que tiene un array de objetos Empleado (clase vista en captulos
anteriores). En esta clase podramos tener mtodos para contratar un Empleado (aadir un nuevo objeto al
array), despedirlo (quilarlo del array) u obtener el nombre a partir del nmero de empleado. La clase podra
ser algo as como lo siguiente:
public class Empresa {
String nombre;
Empleado [] listaEmpleados;
int totalEmpleados = 0;
...
Empresa(String n, int maxEmp) {
nombre = n;
listaEmpleados = new Empleado [maxEmp];
}
...
void nuevoEmpleado(String nombre, int sueldo) {
if (totalEmpleados < listaEmpleados.length ) {
listaEmpleados[totalEmpleados++] = new Empleado(nombre,sueldo);
}
}
}
Observese en el mtodo nuevoEmpleado que se comprueba que hay sitio en el array para almacenar la
referencia al nuevo empleado. Si lo hay se crea el objeto. Pero si no lo hay el mtodo no hace nada ms. No
da ninguna indicacin de si la operacin ha tenido xito o no. Se podra hacer una modificacin para que, por
ejemplo el mtodo devolviera un valor booleano true si la operacin se ha completado con xito y false si ha
habido algn problema.
Otra posibilidad es generar una excepcin verificada (Una excepcin no verificada se producira si no se
comprobara si el nuevo empleado va a caber o no en el array). Vamos a ver como se hara esto.
Las excepciones son clases, que heredan de la clase genrica Exception. Es necesario por tanto asignar un
nombre a nuestra excepcin. Se suelen asignar nombres que den alguna idea del tipo de error que controlan.
En nuestro ejemplo le vamos a llamar CapacidadEmpresaExcedida.
Para que un mtodo lance una excepcin:
Debe declarar el tipo de excepcin que lanza con la clusula throws, en su declaracin.
Debe lanzar la excepcin, en el punto del cdigo adecuado con la sentencia throw.
En nuestro ejemplo:
void nuevoEmpleado(String nombre, int sueldo) throws CapacidadEmpresaExcedida {
if (totalEmpleados < listaEmpleados.length) {
listaEmpleados[totalEmpleados++] = new Empleado(nombre,sueldo);
}
else throw new CapacidadEmpresaExcedida(nombre);
}
Adems, necesitamos escribir la clase CapacidadEmpresaExcedida. Sera algo as:
public class CapacidadEmpresaExcedida extends Exception {
CapacidadEmpresaExcedida(String nombre) {
super("No es posible aadir el empleado " + nombre);
}
...
}
La sentencia throw crea un objeto de la clase CapacidadEmpresaExcedida . El constructor tiene un argumento
(el nombre del empleado). El constructor simplemente llama al constructor de la superclase pasndole como
argumento un texto explicativo del error ( y el nombre del empleado que no se ha podido aadir).
La clase de la excepcin puede declarar otros mtodos o guardar datos de depuracin que se consideren
oportunos. El nico requisito es que extienda la clase Exception. Consultar la documentacin del API para ver
una descripcin completa de la clase Exception.
De esta forma se pueden construir mtodos que generen excepciones.