05 Curso de Java OO. Herencia y Polimorfismo
Resumen: Se estudiara el uso de la herencia y el polimorfismo en el reuso de clases.
I. HERENCIA
1.1 Definición
Permite a una clase compartir la misma estructura de datos y comportamiento de otra clase.
La herencia minimiza la necesidad de duplicar código.
El Polimorfismo permite utilizar el método de acuerdo al objeto heredado.
Superclase : Item
Subclase : Pelicula , Libro , Equipo (DVD, VHS)
Que atributos tienen en común las subclases?
Que atributos no tienen en común las subclases?
Que método no tienen en común las subclases? Defina las subclases Libro y Equipo.
Como declararía las clases:
Hombre > Homínido > Primate > Placentario
Perro > Canino > Carnivoro > Placentario
Placentario > Mamífero > Vertebrado > Animal > Ser Vivo.
1.2. La herencia en Java
Una subclase se define indicando a que superclase extiende.
public class Item {
public class Pelicula extends Item {
// pelicula de otros tipos de item
Una subclase hereda todas las variables instancia de la superclase.
Las variables de instancia deben ser private para que instancias de la subclase hereden sus valores.
public class Item {
protected String estado = "Excelente";
public class Pelicula extends Item {
private int duracion = 0;
1.3. La referencia super
Se refiere a la clase padre
Se usa para invocar constructores de la clase padre
Debe ser la primera sentencia del constructor de la clase hijo
Esta referencia también se usa para invocar cualquier método del padre.
public class Item {
Item (float precio) {
this.precio = precio;
}
public class Pelicula extends Item {
Pelicula (float precio, String titulo) {
this.titulo = titulo;
Una subclase no hereda ningún constructor de la superclase, debe declararse explícitamente.
Solo en caso no se declare explícitamente, se ejecutaran los constructores por defecto de las superclases y finalmente de la subclase.
Pelicula pelicula = new Pelicula ();
// Inicia variables de la clase Item. Constructor por defecto.
// Inicia variables de la clase Pelicula. Constructor por defecto.
1.4. Métodos
La superclase define los métodos para todas las subclases.
La subclase puede especificar métodos propios.
Item0.java
public class Item0 {
Item0 (float precio) {
public float getPrecio() {
Pelicula0.java
public class Pelicula0 extends Item0
{
Pelicula0 (float precio, String titulo) {
this.titulo = titulo;
public String getTitulo()
{
TestSuper.java
public class TestSuper {
System.out.println( item.getPrecio() );
Pelicula0 pelicula = new Pelicula0(2.2f,"Zelig");
System.out.println( pelicula.getPrecio() );
System.out.println( pelicula.getTitulo() );
Que diferencia existe entre this y super?
Se puede reemplazar super(precio); por this.precio = precio; ?
Que métodos puede invocar una subclase?
La subclase hereda todos los métodos del padre.
La subclase puede re-escribir un método del padre.
Item1.java
public class Item1 {
return 50;
}
Pelicula1.java
public class Pelicula1 extends Item1 {
public class TestSobrescribir {
System.out.println( item1.calcularImporte(599) )
Pelicula1 pelicula1 = new Pelicula1();
System.out.println( pelicula1.calcularImporte(399) );
System.out.println( pelicula1.calcularImporte(599) );
Cual es la diferencia entre sobre-carga de métodos y sobre-escritura de métodos?
1.5. La referencia super
Si una subclase sobrescribe un método de la superclase; el método de la superclase se puede invocar con la referencia super.
Item2.java
public class Item2 {
return 50;
}
Equipo2.java
public class Equipo2 extends Item2 {
float alquiler = super.calcularImporte(cliente);
return seguroEquipo + alquiler;
TestSuper2.java
public class TestSuper2 {
System.out.println( articulo.calcularImporte(599) );
Equipo2 vhs = new Equipo2();
System.out.println( vhs.calcularImporte(599) );
2. Polimorfismo
Permite efectuar una misma operación dependiendo del tipo de objeto.
Ejemplo
TacoraFilms inicia sus operaciones alquilando únicamente películas.
Tres meses después amplia el alquiler a equipos, juegos y libros.
El alquiler de una pelicula es 2 soles por día de alquiler.
El alquiler de un equipo consta de un seguro de 50 soles además de 5 soles por día.
El alquiler de juegos depende del fabricante. PlayStation 2soles/día Nintendo 1sol/día
Los libros no se alquilan, se prestan uno a la vez, mientras sean clientes de la tienda.
Explique por que se obtienen los resultados
Alquiler3.java
public class Alquiler3 {
public Alquiler3(int dias) {
public int getDias () {
Item3.java
public class Item3 {
Pelicula3.java
public class Pelicula3 extends Item3 {
return importe;
public class Equipo3 extends Item3 {
int importe = 5*contrato.getDias();
return seguroEquipo + importe;
Juego3.java
public class Juego3 extends Item3 {
public Juego3(String fabricante) {
public String getFabricante() {
protected float calcularImporte(Alquiler3 contrato) {
int tasa = 0;
if (fabricante.equals("PlayStation")) tasa = 2;
if (fabricante.equals("Nintendo")) tasa = 1;
int importe = tasa*contrato.getDias();
return importe;
Libro3.java
public class Libro3 extends Item3 {
TestPolimorfismo.java
public class TestPolimorfismo {
Pelicula3 oscar = new Pelicula3();
System.out.println( oscar.calcularImporte(contrato) );
Equipo3 vhs = new Equipo3();
System.out.println( vhs.calcularImporte(contrato) );
Juego3 mu = new Juego3("Nintendo");
System.out.println( mu.calcularImporte(contrato) );
Libro3 quijote = new Libro3();
System.out.println( quijote.calcularImporte(contrato) );
Ejercicio
Agregue una nueva clase llamada Revista.java cuyo importe se basara en el día de la semana que se alquila.
Si es Sábado o Domingo el alquiler de las revistas será 5, en otro días será 2.
3. El operador instanceof y cast
El operador instanceof permite determinar la clase de un objeto en tiempo de ejecución.
La operación cast permite modificar la clase de un objeto.
El siguiente ejemplo muestra el uso de instanceOf y como el metodo is3D(Punto p) puede reconocerlo
Punto.java
import java.lang.Math;
public class Punto {
public Punto ( int x, int y ) {
this.y = y;
public float distancia() {
Punto3D.java
import java.lang.Math;
public class Punto3D extends Punto {
public Punto3D ( int x, int y, int z ) {
this.z = z;
// Distancia al eje de coordenadas
public float distancia() {
TestInstanceOf.java
public class TestInstanceOf {
public static void main(String[] args) {
Punto p3 = new Punto3D(0,0,10);
System.out.println(is3D(p2));
3.1. TestInstanceOfCast
El cast es implicito al convertir una clase hijo a una la clase padre.
El cast debe ser explicito al convertir de una clase padre a una clase hijo.
public class Movil {
Movil() { nombre = "Movil"; }
public class MovilPesado extends Movil {
public class Camion extends MovilPesado {
public class MovilLigero extends Movil {
public class TestInstanceOfCast {
static MovilPesado pesado = new MovilPesado();
static Camion volvo = new Camion();
static MovilPesado tren = null;
resultado = pesado instanceof MovilPesado;
System.out.print("pesado es un MovilPesado: " + resultado + "\n");
resultado = volvo instanceof MovilPesado;
System.out.print("volvo es un MovilPesado: " + resultado + "\n");
resultado = pesado instanceof Camion;
System.out.print("pesado is a Camion: " + resultado + "\n");
resultado = tren instanceof MovilPesado;
System.out.print("tren es un MovilPesado: " + resultado + "\n");
pesado = volvo; //Cast implicito. Un hijo se convierte en padre.
volvo = (Camion) pesado; //Cast explicito. Un padre se convierte en hijo.
3.2. TestOperador
El cast es implicito al convertir un hijo en padre. Revise aqui el paso de parametros al metodo testOperador.
Para convertir un padre a hijo, se usa cast explicito
public class TestOperador {
Equipo3 vhs = new Equipo3();
Juego3 mu = new Juego3("Nintendo");
Libro3 quijote = new Libro3();
testOperador(oscar);
testOperador(vhs);
testOperador(mu);
testOperador(agua);
public static void testOperador (Item3 articulo) {
System.out.println(juego.getFabricante());
else {
4. Atributos, métodos y clases final
4.1. Variables final
Una variable final es una constante
Una variable final no puede ser modificada
Una variable final debe ser iniciada
Una variable final por lo general es publica para que pueda ser accesada externamente.
Aqui no se puede cambiar los valores de las constantes
public class Constantes {
public final static String NEGRO = "FFFFFF";
public final static float PI = 3.141592f;
public final static int MAXIMO_ITEMS = 10;
NEGRO = '000000';
PI = 3.1416;
MAXIMO_ITEMS = 0;
*/
4.2. Métodos final Un método puede ser definida como final para evitar la sobre-escritura en una subclase.
Un método final no se puede redefinir en una clase hijo.
public final static String getBlanco() {
public final boolean verificarPassword(String password) {
Aqui no se puede sobreescribir el metodo calcularImporte en la clase Pelicula4 por que calcularImporte de su clase padre es final.Item4.java
public class Item4 {
Pelicula4.java
public class Pelicula4 extends Item4 {
if (cliente < 500)
4.3. Clases final
Una clase final no puede ser padre de otra clase.
Una clase puede ser definida como final para evitar la herencia.
El compilador es mas eficiente con definiciones final por que no buscara estas clases o métodos al tratar clases heredadas.
Aqui no se puede extender ninguna clase de Color.java
Color.java
public final class Color {
public final static String getBlanco() {
/* Paleta.java
public final class Paleta.java extends Color.java {
*/
Ejercicio: Realizar lo siguiente.
Librería.java
public final class Libreria {
public final static float PI = 3.141592f;
public final static int getModulo10(int numero)
{
if (numero < 0) numero = -numero;
String cadena = String.valueOf(numero);
int suma = 0;
for (int i=1; i < cadena.length(); i++) {
int digito = Integer.parseInt(caracter);
suma += digito;
int residuo = suma%10;
return residuo;
TestLibreria.java
public class TestLibreria {
System.out.println(Libreria.PI);
System.out.println(Libreria.getModulo10(11));
System.out.println(Libreria.getModulo10(880385));
5. El método finalize()
Cuando todas las referencias de un objeto se pierden, se marcan para que el Garbage Collector los recoja y libere ese espacio en memoria.
Pelicula pelicula = new Pelicula("Zelig");
pelicula = null;
El objeto "Zelig" que estaba referenciado por pelicula ha perdido todas sus referencias.
Luego el Garbage Collector liberara el espacio ocupado por "Zelig"
El método finalize es llamado justo antes que el Garbage Collector libere la memoria. En este instante se puede aprovechar para realizar otras operaciones.
public class Pelicula4 {
public Pelicula4(String titulo) {
public void finalize()
{
globo = null;
Encuentre los errores en el siguiente código.
Item.java
package alquiler;
public class Item {
public String getNombre() return "";
private String getColor() return "";
protected String getImporte() return "";
String getAlias() return "";
public final String getFabricante() return "";
Pelicula.java
package alquiler;
public class Pelicula extends Item {
public String getNombre() return super.getNombre();
private String getColor() return super.getColor();
protected String getImporte() return super.getImporte();
String getAlias() return super.getAlias();
public final String getFabricante()
return super.getFabricante();
Juguete.java
package almacen;
public final class Juguete {
public String getNombre() return item.getNombre();
public String getColor() return item.getColor();
protected String getImporte() return item.getImporte();
String getAlias() return item.getAlias();
Pelota.java
package almacen;
public final class Pelota extends Juguete {
public String getColor() return super.getColor();
protected String getImporte() return super.getImporte();
String getAlias() return super.getAlias();
7. Laboratorio.
Cree una clase Item.java con los siguientes atributos: id (int); titulo, descripción, ranking, categoría (String) , precio de alquiler por dia (double).
Todos estos atributos seran protected.
Agregue un atributo entero privado estático que inicia en 1000 para autogenerar el Id del item.
Agregue un constructor sin parámetros que autogenere un id para el item en base al atributo estático.
Agregue un segundo constructor con argumentos titulo, descripción, precio, ranking y categoría.
Este constructor invocara al primer constructor para asignar el id. Ademas asignara los argumentos a los atributos.
Agregue todos los métodos set y get para cada atributo.
Item.java
public class Item {
protected int id;
...
public Item() {
public Item(String titulo... ) {
this.titulo = titulo...
public int getId()...
...
public void setTitulo(String titulo)...
public String getTitulo()...
...
public static int getSiguienteId()...
La clase Cliente contara con 2 atributos, su id y su nombre. El id se generara automáticamente.
Cliente.java
public class Cliente {
protected int id;
...
public Cliente() {
public Cliente(String nombre) {
this.nombre...
public int getId()...
public String getNombre()...
Cree una clase Pelicula.java que herede de Item.java con los siguientes atributos: duracion (int) y director (String). Estos atributos seran privados.
Agregue un constructor con argumentos titulo, descripción, precio, ranking, numero de dias, categoría, duración y director.
Este constructor invocara al constructor de la superclase y luego asignara los dos ultimos argumentos a sus atributos privados.
Agregue todos los métodos set y get para sus dos atributos privados.
Agregue el método toString() que devuelva todos los atributos privados y heredados
Pelicula.java
public class Pelicula extends Item {
private int duracion;
public Pelicula(String titulo ... int duracion) {
this.director = director;
this.duracion = duracion;
public void setDirector...
public String getDirector...
public void setDuracion...
public String getDuracion...
public String toString...
Cree una clase Juego.java que herede de Item.java con los siguientes atributos: memoria (int) y tipo (String). Estos atributos seran privados.
Agregue un constructor con argumentos titulo, descripción, precio, ranking, numero de dias, categoría, memoria y tipo.
Este constructor invocara al constructor de la superclase y luego asignara los dos últimos argumentos a sus atributos privados.
Agregue todos los métodos set y get para sus dos atributos privados.
Agregue el método toString() que devuelva todos los atributos privados y heredados
Juego.java
public class Juego extends Item {
private String tipo;
public Juego(String titulo ... String tipo) {
this.memoria=...;
this.tipo=...;
...setMemoria...
...getMemoria...
...setTipo...
...getTipo...
public String toString...
En la base de datos se encontraran la lista de películas y los juegos.
BaseDeDatos.java
public class BaseDeDatos {
Items[] item = new Item [4];
public BaseDeDatos() {
//...
item[0] = new Pelicula("La caravana del valor",...);
item[1] = new Pelicula("En las lunas de Endor",...);
item[2] = new Juego("Mu Online",...);
item[3] = new Juego("War Craft",...);
//...
for (...) {
return cliente1;
public static Item getItem(int id) ...
La clase Alquiler.java contara con los siguientes atributos: un arreglo de Ítems que se alquilaran (Item) el cliente que alquila (Cliente) un numero de alquiler id (int), la cantidad de ítems alquilados (int) y la cantidad de dias de alquiler (int).
Un atributo de clase privado estático entero será el contador de id que iniciara en 500.
Una constante será el máximo numero de ítems a alquilar que es 10.
Una constante será el impuesto del alquiler de 19%.
Un constructor asignara el cliente por argumento y el numero de dias de alquiler. También creara el arreglo de ítems, y su numero de alquiler.
Un método para agregar ítems al arreglo de ítems del alquiler.
Un método imprimira todo el detalle del alquiler en pantalla.
Alquiler.java
public class Alquiler {
private int alquilerId;
private int numeroDias;
private int clienteId;
private int cantidadItems;
private int[] itemId;
private final static int MAXITEMS = 10;
private final static double IMPUESTO = 0.19;
...
public Alquiler(int clienteId, int numeroDias) {
this.clienteId = ...
...
itemId = new int[MAXITEMS];
public void agregarItem(int item) {
cantidadItems++;
public void imprimirReporte() {
Dias alquiler: 5
Detalle
1. El Padrino Precio = 1.10
2. Odisea 2001 Precio = 2.20
3. Aeropuerto 77 Precio = 3.30
Importe venta = 33.00
Importe total = 39.27
*/
public class TacoraFilms {
alquiler.agregarItem(1001);
alquiler.agregarItem(1002);
alquiler.agregarItem(1003);
alquiler.imprimerReporte();