Está en la página 1de 21

Informtica III __ Herencia y Polimorfismo usando Java 1

Herencia y Polimorfismo

Introduccin

Hasta lo que hemos desarrollado de este curso se ha destacado una de la propiedades mas importantes
de la programacin orientada a objetas la Abstraccin. La cual se pone de manifiesto en la
Encapsulacin, que consiste en proteger los datos del mundo exterior, permitiendo el acceso a ellos a
travs de una interfase. Las clases como ya conocemos permiten implementar modelos que ayudan al
programador simular situaciones complejas del mundo real. Ahora las clases no son suficientes por si
solas para soportar diseo y programacin orientada a objetos, se requiere de un mecanismo para
relacionar una clase con otra, este mecanismo lo conoceremos por el nombre de Herencia la cual es una
de las caractersticas mas importantes, despus de las clases, en la programacin orientada a objetos.

Herencia

El concepto de herencia constituye, a nuestro juicio, la principal innovacin del desarrollo orientado a
objetos. Se trata de un concepto bastante simple e intuitivo que, de una manera informal, puede
definirse como:

"el mecanismo que permite definir una clase de objetos tomando como base la definicin de otra
clase"

Una clase se define en trminos de atributos y de mtodos (u operaciones). Por tanto, otra forma de
expresar la definicin anterior seria la siguiente:

"herencia es el mecanismo que permite a una clase de objetos incorporar atributos y mtodos de
otra clase, aadindolas a las que ya posee".

En la terminologa habitual, la clase que hereda las caractersticas de otra y la clase de partida reciben
los calificativos de "subclase" y "superclase", respectivamente. De ah que, en numerosas ocasiones, la
relacin de herencia aparezca tambin referenciada como "superclase/subclase".

Por otro lado, tambin suele ser muy habitual hablar en trminos de "clase padre" o clase base y
"clase hija" o clase derivada, dado lo intuitivo de ambos trminos.
Informtica III __ Herencia y Polimorfismo usando Java 2

La ventaja mas importante que nos da la Herencia es la reutilizacin: la cual consiste en la reutilizacin
del cdigo existente en una o mas clases derivando simplemente una clase de ella, en otras palabras es
la flexibilidad que proporciona para capturar y aprovechar al mximo las caractersticas comunes de
diferentes clases de objetos. Dicha flexibilidad se manifiesta, fundamentalmente, en dos sentidos:
Por un lado, permite recoger los aspectos comunes de dos o ms clases de objetos con el
mximo nivel de detalle (a nivel de atributo y de mtodo).
Por otro, ofrece la posibilidad de establecer tantos niveles de abstraccin (o de especializacin,
segn se mire) como sean necesarios para reflejar fielmente nuestro modelo de la realidad.
Surge, de este modo, el concepto de jerarqua de clases

El uso de la herencia en la programacin orientada a objetos implica la creacin de clases a partir de


clases ya existentes, como ejemplo para ilustrar esto podramos tener una clase Casa que consta de una
cocina, un saln, un bao y un dormitorio. Esta clase se podra utilizar como bloque de construccin
para crear casas ms grandes o mansiones, basta aadir a la clase Casa ms dormitorios, ms baos y
ms salones y tendremos una lujosa mansin. Se dice que la clase Mansin se deriva de la clase Casa.
La Clase seria la clase padre, clase base, superclase o ascendiente y la clase Mansin creada a partir de
la clase Casa se llama clase derivada, subclase o clase hija.

Tipos de Herencia

Existen dos tipos de herencia: herencia simple y herencia mltiple. La herencia simple: es aquella en la
cual la clase derivada hereda de una nica clase, lo cual implica que una clase derivada tiene solo un
ascendiente. Cada clase base sin embargo puede tener muchos descendientes en la figura 1 se ilustra
una relacin de herencia simple.

La herencia mltiple: es aquella en la cual la clase derivada tiene mas de una clase base, por lo cual la
clase derivada tiene mas de un ascendiente. La figura 2 ilustra una relacin de herencia mltiple.

A B
Figura 1 Figura 2

C
La figura1 muestra como las clases B y C se derivan de la clase A (herencia simple) mientras que la
figura 2 muestra como la clase derivada C hereda de A y B (herencia mltiple.
Informtica III __ Herencia y Polimorfismo usando Java 3

La importancia del concepto de herencia es tal que, para algunos autores, la presencia o no de
mecanismos que implementen de forma natural este concepto es lo que diferencia a un lenguaje de
programacin orientado a objetos de otro que no lo es. Segn esta tesis, lenguajes como Ada quedaran
excluidos de tal apelativo, en contra de lo que podra deducirse a partir de las numerosas publicaciones
en las que se defienden sus especiales aptitudes para esta nueva modalidad de desarrollo de software.

La ausencia del mecanismo de herencia en ciertos lenguajes de programacin modernos, como Ada,
puede paliarse hasta cierto punto haciendo uso de los mecanismos alternativos que este tipo de
lenguajes incorporan (por ejemplo, los genricos). No obstante, la flexibilidad que proporciona el
mecanismo de herencia para reutilizar unas clases de objetos en la definicin de otras, difcilmente
pueden alcanzarse mediante tales mecanismos alternativos.

Clases derivadas

La herencia es la relacin que existe entre dos clases en la que una clase denominada derivada se crea
a partir de otra clase ya existente llamada clase base, en esta caso la nueva clase puede heredar de la
clase ya existente atributos y mtodos no privados. En Java este proceso de derivacin se lleva a cabo
usando la palabra reservada extends que permite crear clases derivadas o clases que son extensin de
otra clase, siguiendo el siguiente formato:

class nombre_clase_derivada extends nombre_clase_base {

private miembro_privado

public miembro_publico

una vez definida la nueva clase se agregan los nuevos miembros que se requieren para cumplirlas
necesidades especificas de la nueva clase. Por ejemplo toda publicacin tienen en comn una editorial
y una fecha de publicacin, tienen una periodicidad y un tiraje. Los libros en cambio tienen un autor y
cdigo ISBN.
Informtica III __ Herencia y Polimorfismo usando Java 4

Publicacin

Revista Libro

tanto revista como libro heredan de publicacin, por lo que un objeto libro contiene los miembros
heredados de publicacin (no privados) mas los nuevos miembros como el ISBN y el autor, en le caso
de un objeto revista, tambin hereda de publicacin todos los miembros (no privados), mas los nuevos
miembros, periodicidad y tiraje. La implementacin de esto quedara as:

class publicacin {
private String editor, fecha;
public void ieditor( String nombre) {.}
public void ifecha(String fech) {}
}
class revista extends publicacio {
private int nrosanual, tiraje;
public void fnroanual(int n) {..}
public void ftiraje( int t) {}
}
class libro extends publicacion {
private String autor, isbn;
public void iautor( String a) {.}
public void iisbn(String is) {}
}

en consecuencia sern posibles las siguientes operaciones:

libro L1 = new libro( );


Informtica III __ Herencia y Polimorfismo usando Java 5

L1.ieditor(Wrox);
L1.ifecha(20/02/2000);
L1.iautor(Luis Mendez);
L1.iisbn(84-481-2015-9);
revista r1 new revista( );
r1.ieditor(Televisa Internacional);
r1.ifecha(01/10/2003);
r1.fnroanual(12);
r1.ftiraje(300000);

Constructores en herencia

Una clase derivada es una especializacin de una clase base, por lo que, el constructor de la clase base
debe ser llamado primero, ya que de este modo se creara un objeto de la clase base, antes de que le
constructor de la clase derivada realice su trabajo, es decir el objeto de la clase base debe existir
primero antes de se convierta en un objeto de la clase derivada. Resumiendo:

El constructor de la clase base se invoca primero que el de la clase derivada.


Si una clase base es a su vez una clase derivada sus constructores se invocan tambin en
secuencia.

Los constructores no se heredan.

Formato del constructor de la derivada:

public nombre_constructor_clase_derivada (lista_parametros) {


super(lista_parametros);
//cuerpo constructor clase derivada
}

la primera lnea del constructor de la clase derivada debe incluir una llamada al constructor de la clase
base, hacindola a travs de la palabra clave super( ), incluyendo los argumentos que se vayan a pasar.
Como observamos el constructor de la clase derivada tiene dos tareas:
Informtica III __ Herencia y Polimorfismo usando Java 6

Inicializar el objeto base.


Inicializar los datos miembros de la clase derivada.

class persona {
Private String nombre;
Public persona (String n) { nombre = new String(n); }
}
class joven extends persona {
private int edad;
public joven (String np, int ed) {
super(np); //llamada al constructor de la clase base
edad = ed;
}
}

el constructor de la clase derivada recibe tantos los argumentos para inicializar los datos de la clase
base como los valores para inicializar los datos de la clase derivada.

Mtodos miembros de la clase derivada

Se definen de la misma manera como se ha hecho hasta ahora. Directamente en el cuerpo de la clase.
Los mtodos de la clase base pueden ser llamados desde la clase derivada escribiendo su nombre e
indicando sus argumentos.

Sobreposicin: implica rescribir como un mtodo trabaja internamente sin cambiar el encabezado del
mismo.

En ocasiones ocurre que hay mtodos de la clase base que no interesa que sean heredados en la clase
derivada con la funcionalidad que estos tienen. Para solucionar esto simplemente rescribimos el
mtodo en la clase derivada. Por ejemplo digamos que tenemos definida una clase estudiante con los
miembros siguientes:

Class estudiante {
Private String nombre, cedula;
//Otros miembros..
Public void mostrar( ) {
System.out.println(Nombre: + nombre);
System.out.println(Cdula: + cedula);
}
}
Informtica III __ Herencia y Polimorfismo usando Java 7

por herencia todas las clases derivadas de estudiante heredaran el mtodo mostrar( ), sin embargo aqu
hay un problema, si definimos una clase graduado que hereda de estudiante esta tendr dos nuevos
atributos, grado_obtenido y fecha_graduacion. Si invocamos el mtodo mostrar para un estudiante
graduado mostrara los dos atributos heredados de estudiante porque estos son los nicos atributos que
el mtodo mostrar tiene incluido en su cdigo como salida de datos. Idealmente nos gustara que le
mtodo mostrar( ) cuando fuera invocado por graduado mostrara los atributos de estudiante mas los dos
atributos adicionales de graduado, para lograr esto rescribimos mostrar( ) de la manera siguiente:

class graduado extends estudiante {


private String grado_obtenido, fecha_graduacion;
// Otros miembros
public void mostrar( ) {
super.mostrar( ); //invocamos mostrar de estudiante
System.out.println(Grado obtenido: + grado_obtenido);
System.out.println(Fecha de graduacin: + fecha_graduacion);
}
}

la primera lnea del mtodo mostrar( ) usamos la palabra reservada super como prefijo del mensaje
super.mostrar( ) cuando deseamos invocar la versin de un mtodo que fue definido en una clase base.
Esto evita que tengamos que duplicar el cdigo en la versin de mostrar de graduado, agregando
solamente los atributos de la clase derivada. Note que en todos los casos los encabezados de los
mtodos permanecen iguales (public void mostrar( ) ) para que la sobreposicin tome lugar.

Liberacin de los objetos de una clase derivada

La liberacin de una instancia de una clase derivada no se distingue de la liberacin de un objeto de


una no derivada, simplemente se libera la memoria.

Sobrecarga de mtodos en la clase derivada


Informtica III __ Herencia y Polimorfismo usando Java 8

Una clase derivada puede redefinir un mtodo de la clase base, teniendo el mismo nombre pero
diferente lista de argumentos. Esta redefinicin en la clase derivada no oculta el mtodo de la clase
base; sino que da lugar a una sobrecarga del mtodo en la clase derivada.
Informtica III __ Herencia y Polimorfismo usando Java 9

Conversin de objetos de la clase derivada y la clase base

Al declarar una clase como derivada de otra clase, los objetos de la clase derivada son a su vez objetos
de la clase base. Volvamos al ejemplo de la publicacin y sus clases derivadas libro y revista. Un objeto
libro es a su vez un objeto publicacin, pudiendo afirmar, que todo libro es una publicacin. Un
lenguaje que soporte la programacin orientada a objetos hace una conversin automtica de una
referencia a clase derivada a referencia a clase base.

publicacin p;
libro l = new libro( );
revista r = new revista( );
p = l; //conversin automatica
p = r; //conversin automatica

no es posible la conversin inversa de un objeto de la clase base a referencia de la clase derivada o sea :

publicacin p1 = new publicacin( );


revista r1 = new revista( );
r = p; //incorrecto; error de conversin

Polimorfismo

El termino polimorfismo se refiere a la habilidad de dos o mas objetos pertenecientes a clases


diferentes a responder; a responder, al mismo mensaje de diferente manera. Si le damos a tres
profesionales: un cirujano, un barbero y a un actor, la orden corten, el cirujano hara un incisin, el
barbero comenzara a cortar algo de pelo y el actor detendra abruptamente la accin de una escena.
Estos tres profesionales podran objetos pertenecientes a diferentes clases de profesionales, a cada uno
se le a dado el mismo mensaje, corten, pero cada uno sabia el significado que tenia este mensaje, en
virtud de conocer la profesin a la cual estn asociados.

Volvamos a la clase estudiante:


Class estudiante {
// Otros miembros omitidos..
Public void mostrar( ) {
System.out.println(Nombre: + nombre);
Informtica III __ Herencia y Polimorfismo usando Java 10

System.out.println(Cedula : + cedula);
}
}
class graduado extends estudiante{
// Otros miembros omitidos..
public void mostrar( ) {
Super.mostrar( ) ;
System.out.println(Grado obtenido: + grado_obtenido);
System.out.println(Fecha grado : + fecha_graduacion);
}
}

class nograduado extends estudiante{


// Otros miembros omitidos..
public void mostrar( ) {
Super.mostrar( ) ;
System.out.println(Carrera: + carrera);
System.out.println(Semestre : + semestre);
}
}

asumamos que creamos un arreglo llamado Colegio declarado para mantener referencias a objetos
estudiantes, y colocamos en estas referencias, referencias a graduados y no graduados (ambas son
subclases de estudiante), como se muestra a continuacin:

estudiante Colegio[ ] = new estudiante[4]; //declaramos el arreglo colegio


graduado g1 = new graduado( ); // instanciamos varios tipos de objetos estudiante
graduado g2 = new graduado( );
nograduado n1 = new nograduado( );
nograduado n2 = new nograduado( );
// llenar el arreglo con estos objetos
Colegio[0] = g1;
Informtica III __ Herencia y Polimorfismo usando Java 11

Colegio[1] = n1;
Colegio[2] = g2;
Colegio[3] = n2;

Anteriormente habamos establecido que el mtodo mostrar( ) definido en estudiante no es suficiente


para mostrar los atributos de las subclases graduado y nograduado, porque el cdigo asociado a este
mtodo no conoce de los atributos que fueron agregados a estas subclases, asi que, sobreponemos el
mtodo mostrar( ) de estudiante para crear variaciones especiales de mostrar( ) en todas las subclases
como mostramos en el cdigo antes escrito.

Ahora queremos imprimir los atributos de todos los estudiantes que tenemos en el arreglo Colegio,
veamos el siguiente cdigo:

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


Colegio[i].mostrar( );
}

Cuando recorremos los elementos del arreglo, uno por uno, cada objeto automticamente sabe cual
versin de mostrar( ) deber ejecutar, basado en la clase ala cual el pertenece, la lnea de cdigo:

Colegio[i].mostrar( );

Se dice que es polimorfica, porque le mtodo ejecutado en respuesta al mensaje puede tener diferentes
formas dependiendo de la clase a la que pertenece el objeto.

Mtodos Abstractos

Todo mtodo que este precedido de la palabra reservada abstract, le notifica al compilador que la
definicin del mtodo se har en la clase derivada, formato:

abstract nombre_metodo (argumentos);

Cada clase derivada debe definir su versin de los mtodos abstractos que han sido declarados en la
clase base. Toda clase con uno o ms mtodos abstractos es una clase abstracta.
Informtica III __ Herencia y Polimorfismo usando Java 12

Clases Abstractas

Son clases que proporcionan una clase base adecuada, a partir de la cual derivamos otras clases. Estas
clases son demasiados genricas, con ellas, no se pueden instanciar objetos. Las clases de las cuales se
pueden instanciar objetos se denominan clases concretas.

Una clase abstracta puede definir datos miembros y mtodos no abstractos, aunque no podemos crear
objetos de una clase abstracta, podemos declarar variables las cuales se pueden utilizar para permitir la
manipulacin polimorfica de los objetos de la clase derivada, cuando tales objetos se instancian a partir
de clases concretas.

En la programacin polimorfica un programa puede recorrer un arreglo de referencias a objetos, las


cuales sern referencias de clases base a objetos de clase derivada. El envi de un mensaje (como
Colegio[i].mostrar( ); en el arreglo Colegio) a uno de los objetos del arreglo, mediante el polimorfismo,
se activara el mtodo correcto de acuerdo al objeto referenciado.

Una clase abstracta se declara con la palabra reservada abstract, formato:

abstract class nombre_clase {


cuerpo clase
}

Tiene al menos un mtodo abstracto, una clase derivada que no modifique un mtodo abstracto es
tambin una clase abstracta.

Desarrollaremos un ejemplo para poner de manifiesto todo lo expresado hasta ahora. Consideremos las
figuras planas cerradas como el rectngulo, y el crculo. Tales figuras comparten caractersticas
comunes como es la posicin de la figura, de su centro, y el rea de la figura, aunque el procedimiento
para calcular dicha rea sea completamente distinto. Podemos por tanto, disear una jerarqua de
clases, tal que la clase base denominada Figura, tenga las caractersticas comunes y cada clase derivada
las especficas. La relacin jerrquica se muestra en la figura
Informtica III __ Herencia y Polimorfismo usando Java 13

La clase Figura es la que contiene las caractersticas comunes a dichas figuras concretas por tanto, no
tiene forma ni tiene rea. Esto lo expresamos declarando Figura como una clase abstracta, declarando
la funcin miembro area abstract.

Las clases abstractas solamente se pueden usar como clases base para otras clases. No se pueden crear
objetos pertenecientes a una clase abstracta. Sin embargo, se pueden declarar variables de dichas clases.

En el juego del ajedrez podemos definir una clase base denominada Pieza, con las caractersticas
comunes a todas las piezas, como es su posicin en el tablero, y derivar de ella las caractersticas
especficas de cada pieza particular. As pues, la clase Pieza ser una clase abstracta con una funcin
abstract denominada mover, y cada tipo de pieza definir dicha funcin de acuerdo a las reglas de su
movimiento sobre el tablero.

La clase Figura

La definicin de la clase abstracta Figura, contiene la posicin x e y de la figura particular, de su


centro, y la funcin area, que se va a definir en las clases derivadas para calcular el rea de cada figura
en particular.

public abstract class Figura {


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

La clase Rectangulo
Informtica III __ Herencia y Polimorfismo usando Java 14

Las clases derivadas heredan los miembros dato x e y de la clase base, y definen la funcin area,
declarada abstract en la clase base Figura, ya que cada figura particular tiene una frmula distinta para
calcular su rea. Por ejemplo, la clase derivada Rectangulo, tiene como datos, aparte de su posicin (x,
y) en el plano, sus dimensiones, es decir, su anchura ancho y altura alto.

class Rectangulo extends Figura{


protected double ancho, alto;
public Rectangulo(int x, int y, double ancho, double alto){
super(x,y);
this.ancho=ancho;
this.alto=alto;
}
public double area(){
return ancho*alto;
}
}

La primera sentencia en el constructor de la clase derivada es una llamada al constructor de la clase


base, para ello se emplea la palabra reservada super. El constructor de la clase derivada llama al
constructor de la clase base y le pasa las coordenadas del punto x e y. Despus inicializa sus miembros
dato ancho y alto.

En la definicin de la funcin area, se calcula el rea del rectngulo como producto de la anchura por la
altura, y se devuelve el resultado

La clase Circulo

class Circulo extends Figura{


protected double radio;
public Circulo(int x, int y, double radio){
super(x,y);
this.radio=radio;
}
public double area(){
return Math.PI*radio*radio;
}
}

Como vemos, la primera sentencia en el constructor de la clase derivada es una llamada al constructor
de la clase base empleando la palabara reservada super. Posteriormente, se inicializa el miembro dato
radio, de la clase derivada Circulo.
Informtica III __ Herencia y Polimorfismo usando Java 15

En la definicin de la funcin area, se calcula el rea del crculo mediante la conocida frmula r2, o
bien *r*r.

Uso de la jerarqua de clases

Creamos un objeto c de la clase Circulo situado en el punto (0, 0) y de 5.5 unidades de radio.
Calculamos y mostramos el valor de su rea.

Circulo c=new Circulo(0, 0, 5.5);


System.out.println("Area del crculo "+c.area());

Creamos un objeto r de la clase Rectangulo situado en el punto (0, 0) y de dimensiones 5.5 de anchura
y 2 unidades de largo. Calculamos y mostramos el valor de su rea.

Rectangulo r=new Rectangulo(0, 0, 5.5, 2.0);


System.out.println("Area del rectngulo "+r.area());

Veamos ahora, una forma alternativa, guardamos el valor devuelto por new al crear objetos de las
clases derivadas en una variable f del tipo Figura (clase base).

Figura f=new Circulo(0, 0, 5.5);


System.out.println("Area del crculo "+f.area());
f=new Rectangulo(0, 0, 5.5, 2.0);
System.out.println("Area del rectngulo "+f.area());

Enlace dinmico

En el lenguaje C, los identificadores de la funcin estn asociados siempre a direcciones fsicas antes
de la ejecucin del programa, esto se conoce como enlace temprano o esttico. Ahora bien, el lenguaje
C++ y Java permiten decidir a que funcin llamar en tiempo de ejecucin, esto se conoce como enlace
tardo o dinmico. Vamos a ver un ejemplo de ello.

Podemos crear un arreglo de la clase base Figura y guardar en sus elementos los valores devueltos por
new al crear objetos de las clases derivadas.

Figura[] fig=new Figura[4];


Informtica III __ Herencia y Polimorfismo usando Java 16

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);

La sentencia

fig[i].area();

a qu funcin area llamar?. La respuesta ser, segn sea el ndice i. Si i es cero, el primer elemento
del array guarda una referencia a un objeto de la clase Rectangulo, luego llamar a la funcin miembro
area de Rectangulo. Si i es uno, el segundo elemento del array guarda una referencia un objeto de la
clase Circulo, luego llamar tambin a la funcin area de Circulo, y as sucesivamente. Pero podemos
introducir el valor del ndice i, a travs del teclado, en el momento en el que se ejecuta el programa.
Luego, la decisin sobre qu funcin area se va a llamar se retrasa hasta el tiempo de ejecucin.

El polimorfismo en accin

Supongamos que deseamos saber la figura que tiene mayor rea independientemente de su forma.
Primero, programamos una funcin que halle el mayor de varios nmeros reales positivos.

double valorMayor(double[] x){


double mayor=0.0;
for (int i=0; i<x.length; i++)
if(x[i]>mayor){
mayor=x[i];
}
return mayor;
}

Ahora, la llamada a la funcin valorMayor

double numeros[]={3.2, 3.0, 5.4, 1.2};


System.out.println("El valor mayor es "+valorMayor(numeros));

La funcin figuraMayor que compara el rea de figuras planas es semejante a la funcin valorMayor
anteriormente definida, se le pasa el array de objetos de la clase base Figura. La funcin devuelve una
referencia al objeto cuya rea es la mayor.
Informtica III __ Herencia y Polimorfismo usando Java 17

static Figura figuraMayor(Figura[] figuras){


Figura mFigura=null;
double areaMayor=0.0;
for(int i=0; i<figuras.length; i++){
if(figuras[i].area()>areaMayor){
areaMayor=figuras[i].area();
mFigura=figuras[i];
}
}
return mFigura;
}

La clave de la definicin de la funcin est en las lneas

if(figuras[i].area()>areaMayor){
areaMayor=figuras[i].area();
mFigura=figuras[i];
}

En la primera lnea, se llama a la versin correcta de la funcin area dependiendo de la referencia al


tipo de objeto que guarda el elemento figuras[i] del array. En areaMayor se guarda el valor mayor de
las reas calculadas, y en mFigura, la figura cuya rea es la mayor.

La principal ventaja de la definicin de esta funcin estriba en que la funcin figuraMayor est definida
en trminos de variable figuras de la clase base Figura, por tanto, trabaja no solamente para una
coleccin de 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());
Informtica III __ Herencia y Polimorfismo usando Java 18

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.

Ampliamos el rbol jerrquico de las clases que describen las figuras planas regulares, para acomodar a
dos clases que describen las figuras planas, tringulo y cuadrado. La relacin jerrquica se muestra en
la figura.

La clase Cuadrado

La clase Cuadrado es una clase especializada de Rectangulo, ya que un cuadrado tiene los lados
iguales. El constructor solamente precisa de tres argumentos los que corresponden a la posicin de la
figura y a la longitud del lado

class Cuadrado extends Rectangulo{


public Cuadrado(int x, int y, double dimension){
super(x, y, dimension, dimension);
}
}

El constructor de la clase derivada llama al constructor de la clase base y le pasa la posicin x e y de la


figura, el ancho y alto que tienen el mismo valor. No es necesario redefinir una nueva funcin area. La
clase Cuadrado hereda la funcin area definida en la clase Rectangulo.
Informtica III __ Herencia y Polimorfismo usando Java 19

La clase Triangulo

La clase derivada Tringulo, tiene como datos, aparte de su posicin (x, y) en el plano, la base y la
altura del tringulo.

class Triangulo extends Figura{


protected double base, altura;
public Triangulo(int x, int y, double base, double altura){
super(x, y);
this.base=base;
this.altura=altura;
}
public double area(){
return base*altura/2;
}
}

El constructor de la clase Triangulo llama al constructor de la clase Figura, le pasa las coordenadas x e
y de su centro, y luego inicializa los miembros dato base y altura.

En la definicin de la funcin area, se calcula el rea del tringulo como producto de la base por la
altura y dividido por dos.

El polimorfismo en accin

Veamos ahora la llamada a la funcin figuarMayor. Primero, creamos un array del tipo Figura,
guardando en sus elementos las direcciones devueltas por new al crear cada uno de los objetos.

Figura[] fig=new Figura[4];


fig[0]=new Rectangulo(0,0, 5.0, 2.0);
fig[1]=new Circulo(0,0, 3.0);
fig[2]=new Cuadrado(0, 0, 5.0);
fig[3]=new Triangulo(0,0, 7.0, 12.0);

Figura fMayor=figuraMayor(fig);
System.out.println("El rea mayor es "+fMayor.area());
Informtica III __ Herencia y Polimorfismo usando Java 20

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 guarda 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 Triangulo, llamar a la funcin
area definida en dicha clase, y as sucesivamente.

El operador instanceof

El operador instanceof tiene dos operandos: un objeto en el lado izquierdo y una clase en el lado
derecho. Esta expresin devuelve true o false dependiendo de que el objeto situado a la izquierda sea o
no una instancia de la clase situada a la derecha o de alguna de sus clases derivadas.

Por ejemplo.

Rectangulo rect=new Rectangulo(0, 0, 5.0, 2.0);


rect instanceof String //false
rect instanceof Rectangulo //true

El objeto rect de la clase Rectangulo no es un objeto de la clase String. El objeto rect si es un objeto de
la clase Rectangulo.

Veamos la relacin entre rect y las clases de la jerarqua

rect instanceof Figura //true


rect instanceof Cuadrado //false

rect es un objeto de la clase base Figura pero no es un objeto de la clase derivada Cuadrado

Resumen

La herencia es la propiedad que permite la creacin de nuevas clases a partir de clases ya existentes. La
clase derivada hereda los datos y las funciones miembros de la clase base, y puede redefinir algunas de
las funciones miembro o definir otras nuevas, para ampliar la funcionalidad que ha recibido de la clase
base.
Informtica III __ Herencia y Polimorfismo usando Java 21

Para crear un objeto de la clase derivada se llama primero al constructor de la clase base mediante la
palabra reservada super. Luego, se inicializa los miembros dato de dicha clase derivada

El polimorfismo se implementa por medio de las funciones abstractas, en las clases derivadas se
declara y se define una funcin que tiene el mismo nombre, el mismo nmero de parmetros y del
mismo tipo que en la clase base, pero que da lugar a un comportamiento distinto, especfico de los
objetos de la clase derivada.

Enlace dinmico significa que la decisin sobre la funcin a llamar se demora hasta el tiempo de
ejecucin del programa.

No se pueden crear objetos de una clase abstracta pero si se pueden declarar referencias en las que
guardamos el valor devuelto por new al crear objetos de las clases derivadas. Esta peculiaridad nos
permite pasar un objeto de una clase derivada a una funcin que conoce el objeto solamente por su
clase base. De este modo podemos ampliar la jerarqua de clases sin modificar el cdigo de las
funciones que manipulan los objetos de las clases de la jerarqua.

También podría gustarte