Está en la página 1de 18

1

Polimorfismo
Jerarqua de clases
Mtodos y clases abstractas
Enlace esttico y dinmico
Forzamiento hacia arriba (upcasting)
Forzamiento hacia abajo (downcasting)
Polimorfismo
M. en C. Rafael Aguilar Garca
Rafael Aguilar Garca ESCOM - IPN

Jerarqua de clases
2

Una jerarqua de clases parte de lo ms general


hacia lo ms particular.
La clase base albergar los comportamientos ms
generales, los cuales se irn especializando en las
subclases.
Los comportamientos generales de la clase base no
pueden ser definidos (con cdigo) en este nivel, por
lo que tendrn que ser declarados como mtodos
abstractos (abstract para Java y virtual para C++).
Cuando una clase tiene al menos un mtodo
abstracto, la clase tendr que ser declarada como
clase abstracta.
Rafael Aguilar Garca ESCOM - IPN

Jerarqua de clases
3

La siguiente jerarqua de clases para la clase


Figura ilustra el concepto de mtodos y clases
abstractas:

Rafael Aguilar Garca ESCOM - IPN

Rafael Aguilar Garca ESCOM - IPN

La clase Figura es declarada como abstracta (abstract)


porque sus mtodos dibujar y obtenerArea no pueden ser
definidos an debido a que todava no conocemos el tipo
de figura.

La clase Figura no
puede ser instanciada
por ser una clase
abstracta

Los mtodos dibujar y obtenerArea son definidos por cada una de las clases
Circulo, Rectngulo y Tringulo. Estas clases pueden ser instanciadas por ser
Rafael Aguilar Garca ESCOM - IPN
clases concretas.

Jerarqua de clases
6

El cdigo Java para la jerarqua de clases anterior


se muestra a continuacin:

Rafael Aguilar Garca ESCOM - IPN

La clase debe ser declarada como clase abstracta


debido a que tiene ms de un mtodo abstracto.
abstract class Figura {
private String nombre;
abstract public double obtenerArea();
abstract public void dibujar();

Los mtodos abstractos no tienen


definicin (cuerpo). Solamente deben
ser declarados como abstractos

public Figura (String nomFigura) {


nombre = nomFigura;
}
public boolean mayorQue (Figura fig) {
return(this.obtenerArea() > fig.obtenerArea());
}
public String toString () {
return ( _nombre + " , " + obtenerArea() );
}

La referencia fig puede tomar


como valor una instancia de Crculo,
Rectngulo, o Tringulo

Rafael Aguilar Garca ESCOM - IPN

class Circulo extends Figura


{
private double radio;
private static final double PI = 3.1416;
public Circulo (double r) {
super("Circulo");
radio = r;
}

Invocacin del constructor


de la clase base Figura.

public Circulo () {
this(10.0);
}
public double obtenerArea() {
return ( PI * radio * radio );
}

La clase Crculo proporciona su


propia definicin de los mtodos
dibujar y obtenerArea. La clase
Circulo es por lo tanto una clase
concreta.

public void dibujar() {


System.out.println("Soy un Circulo con radio: " + radio);
}
}

Rafael Aguilar Garca ESCOM - IPN

class Rectangulo extends Figura


{
private double base;
private double altura;
public Rectangulo (double b, double a) {
Invocacin del constructor
super ("Rectangulo");
base = b;
de la clase base Figura.
altura = a;
}
public Rectangulo () {
this(10.0, 10.0);
La clase Rectngulo proporciona su
}
public double obtenerArea () {
return ( base * altura );
}

propia definicin de los mtodos


dibujar y obtenerArea. La clase
Rectngulo es por lo tanto una clase
concreta.

public void dibujar () {


System.out.println ("Soy un Rectangulo de: " + base +
"*" + altura);
}
}

Rafael Aguilar Garca ESCOM - IPN

class Triangulo extends Figura


{
private double base;
private double altura;
public Triangulo(double b, double a) {
super (Triangulo");
base = b;
altura = a;
}
public Triangulo() {
this(10.0, 10.0);
La
}
public double obtenerArea () {
return ( base*altura/2 );
}

Invocacin del constructor


de la clase base Figura.

clase Tringulo proporciona su


propia definicin de los mtodos
dibujar y obtenerArea. La clase
Tringulo es por lo tanto una clase
concreta.

public void dibujar () {


System.out.println ("Soy un Triangulo de: " + base +
"*" + altura);
}
}

10

Rafael Aguilar Garca ESCOM - IPN

1 class UsoFiguras{
2
public static void main (String[] args) {
3
Figura[] grupo = new Figura[3];
4
int mayor;
5
6
grupo[0] = new Circulo();
7
grupo[1] = new Rectangulo(55);
8
grupo[2] = new Triangulo(20,30);
9
10
for (int i=0; i<grupo.length; i++) {
11
System.out.println(grupo[i]);
12
System.out.println("Area: " + grupo[i].obtenerArea());
13
System.out.println("Dibujar:");
14
grupo[i].dibujar();
15
}
16
17
if (grupo[0].mayorQue(grupo[1])) mayor = 0;
18
else mayor = 1;
19
if (grupo[2].mayorQue(grupo[mayor])) mayor = 2;
20
System.out.println("La figura mayor es:");
21
System.out.println(grupo[mayor]);
22
}
23 }
11

Rafael Aguilar Garca ESCOM - IPN

Polimorfismo
12

La clase UsoFiguras ilustra el uso de la jerarqua de


clases de Figura. A continuacin la descripcin:
En la lnea 3 tenemos un arreglo de referencias a la
clase Figura. Es importante notar que no se est
instanciando un arreglo de objetos Figura; una clase
abstracta no puede tener instancias:
grupo
Figura
Figura

Figura
Rafael Aguilar Garca ESCOM - IPN

Upcasting
13

En la lnea 6 se lleva a cabo el upcasting, esto es, asignamos una


referencia de una subclase (Circulo) a una referencia de una
superclase (Figura).
A travs de una referencia a Figura podemos invocar los mtodos
dibujar y obtenerArea del objeto de la clase Crculo, debido a que
Figura conoce ambos mtodos.
upcasting
Figura
grupo[0] = new Circulo();

Circulo

grupo
grupo[0]

upcasting

Circulo

Rafael Aguilar Garca ESCOM - IPN

Polimorfismo
14

En las lneas 7 y 8 tambin realizamos el upcasting,


ahora para Rectngulo y Tringulo.
En la sentencia for de la lnea 10 se ilustra el
polimorfismo. Aqu recorremos el arreglo grupo y
segn a qu objeto est apuntando la referencia
(grupo[i]) se invocarn sus mtodos correspondientes.
Si la referencia grupo[i] apunta al objeto de
Rectngulo entonces se invocarn los mtodos
obtenerArea y dibujar de la clase Rectngulo, y as
sucesivamente para las otras clases.
Rafael Aguilar Garca ESCOM - IPN

Polimorfismo, enlace dinmico y


esttico
15

Decimos entonces que los mtodos obtenerArea, y


dibujar son polimrficos porque son los mismos nombres
en las subclases, pero con definiciones diferentes en
cada una de ellas. El mtodo invocado ser el
correspondiente al objeto apuntado por la referencia
de tipo Figura (grupo[i]).
Los mtodos del cuerpo de la sentencia for se resuelven
en tiempo de ejecucin y a esto le llamamos enlace
dinmico; no es posible resolver la invocacin de los
mtodos en tiempo de compilacin (enlace esttico)
porque se desconocen los objetos en este momento.
Rafael Aguilar Garca ESCOM - IPN

Downcasting
16

En el downcasting nosotros requerimos ir hacia


abajo en la jerarqua de clases: a partir de una
referencia a una superclase hacemos referencia a
una subclase.
El downcasting requiere de un cast (moldeo)
explcito.
El cdigo siguiente ilustra el uso del downcasting.

Rafael Aguilar Garca ESCOM - IPN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

17

class Animal {
void hacerRuido() {System.out.println(Ruido generico");}
}
class Can extends Animal {
void hacerRuido() {System.out.println(Ladrar"); }
void jugar()
{ System.out.println(Dar vueltas");}
}
class UsoDowncasting{
public static void main (String[] args) {

Animal [] a = {new Animal(), new Can(), new Animal() };


for(Animal animal : a) {
animal.hacerRuido();
if(animal instanceof Can) {
Can d = (Can) animal; // Downcasting: cast explcito
d.jugar();
}
}

Rafael Aguilar Garca ESCOM - IPN

Downcasting
18

En la lnea 16 se ilustra el uso del downcasting.


Aqu requerimos bajar una referencia de la clase
Animal a un subtipo de ella que es la clase Can.
Se requiere de un cast explcito con el propsito de
asegurarnos de que la referencia de la clase Animal
est apuntando efectivamente a una referencia de la
clase Can, debido a que queremos invocar un mtodo
especfico de la clase Can.
El compilador debe estar seguro de esto: primero nos
aseguramos con el operador instanceof de que la
referencia (animal) apunta a un objeto Can y solo
entonces aplicamos el cast: (Can)
Rafael Aguilar Garca ESCOM - IPN