Documentos de Académico
Documentos de Profesional
Documentos de Cultura
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
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:
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) {}
}
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:
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
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.
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:
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.
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
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 :
Polimorfismo
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);
}
}
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:
Colegio[1] = n1;
Colegio[2] = g2;
Colegio[3] = n2;
Ahora queremos imprimir los atributos de todos los estudiantes que tenemos en el arreglo Colegio,
veamos el siguiente cdigo:
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:
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.
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 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.
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
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.
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.
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.
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).
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.
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.
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
if(figuras[i].area()>areaMayor){
areaMayor=figuras[i].area();
mFigura=figuras[i];
}
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.
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
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.
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 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.
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.
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.