Académique Documents
Professionnel Documents
Culture Documents
Herencia
Sperclases y subclases
La clase de la cual se deriva otra clase se denomina clase base, sperclase o clase padre. Una clase derivada de una sperclase recibe tambin el nombre de subclase o clase hija.
Vehculo
Sperclase Clase base Clase padre Subclase Clase derivada Clase hija
Sperclases y subclases
La subclases heredan propiedades de su sperclase. Una subclase, respecto de su sperclase:
Agrega nuevas propiedades Modifica propiedades heredadas.
Vehculo
Camin
Camin
Vehculos terrestres
Vehculos acuticos
Vehculo
Vehculos anfibios
Camin
Ejemplo (1/2)
Determinar si en las siguientes situaciones existe una relacin de herencia entre las clases (indicadas en negrita): Caso 1
Todo Electrodomstico se enciende y apaga. El Horno microondas adems abre y cierra su puerta.
Caso 2
Los Bienes races tienen un Rol de identificacin. Una Casa tiene tambin un Jefe de hogar y un Negocio tiene una Patente comercial
Caso 3
Un Camin tiene Patente. Un Conductor tiene un camin conducido.
Alumno
Profesor
Alumno pregrado
Electrodomstico
Bien Raz
Horno Microondas
7 Franco Guidi Polanco
Casa
Negocio
Ejemplo (2/2)
Determinar si en las siguientes situaciones existe una relacin de herencia entre las clases (indicadas en negrita): Caso 4
Los Archivos Multimediales pueden ser Imgenes o Msica. Las imgenes pueden ser a Color o Blanco y Negro.
Caso 5
Un Avin tiene Fuselaje, Alas y Motores.
Caso 6
Una Gaviota vuela. Una Abeja vuela y adems tiene aguijn.
Ejemplo:
Color
Franco Guidi Polanco
X X
Atributos: - RUT - Nombre Operaciones: -set y get RUT - set y get Nombre Operaciones: Atributos: -set y get RUT - RUT - set y get Nombre - Nombre - set y get Rol UCV - Rol UCV
Persona Alumno
9 Franco Guidi Polanco
10
Implementacin de jerarquas de herencia: ejemplo Implementar las clases Persona y Alumno, de acuerdo con lo siguiente:
public class Persona { public String rut; public String nombre; public Persona() { rut = "00000000-0"; nombre = ""; } public void setRut(String r){ rut = r; } public String getRut(){ return rut; } public void setNombre(String n){ nombre = n; } public String getNombre(){ return nombre; } }
public class Alumno extends Persona { public String rolUCV; public Alumno() { rolUCV = 000000-0"; } public void setRolUCV(String r){ rolUCV = r; } public String getRolUCV(){ return rolUCV; }
public String quinSoy(){ return rut + nombre + rolUCV;
Persona
Alumno
} }
Sperclase
Franco Guidi Polanco
Subclase
12
Miembros heredados (verdad parcial) Una subclase hereda de su sperclase (por el momento):
Variables de instancia pblicas Mtodos pblicos
Todos los anteriores pueden ser utilizados en la subclase como si hubieran sido declarados en ella .
Ejercicio Implemente las clases Vehculo, Autobs y Camin, dados los siguientes antecedentes: Todo Vehculo tiene patente y marca. Los Autobuses y los Camiones son Vehculos. Todo Autobs tiene cantidad de asientos. Todo Camin tiene carga en toneladas.
Veremos:
Un problema de diseo e implementacin con herencia, utilizando miembros pblicos. Se desarrollar una extensin del sistema desarrollado en el problema.
Franco Guidi Polanco 15 Franco Guidi Polanco 16
Implementacin Vehculo:
public class Vehiculo{ public String patente; public String marca; public void setPatente(String p){ patente = p; } public String setMarca(String m){ marca = m; } public String getPatente(){ return patente; } public String getMarca(){ return marca; } }
17 Franco Guidi Polanco 18
Vehculo
Patente, marca
Asientos
Autobs
Camin
Carga
Implementacin Autobs
public class Autobus extends Vehiculo{ public int asientos; public void setAsientos(int a){ asientos = a; } public int getAsientos(){ return asientos; } } }
Implementacin Camin:
public class Camion extends Vehiculo{ public int carga; public void setCarga(int c){ carga = c; } public int getCarga(){ return carga; }
19
20
Uso de las clases desarrolladas Entonces una aplicacin podra realizar lo siguiente:
public class Ejemplo { public static void main( String arg[]){ Autobus bus1 = new Autobus(); bus1.setPatente( AX1313 ); Mtodos heredados de Vehculo bus1.setMarca( Mercedes ); bus1.setAsientos( 40 ); Camion cam1 = new Camion(); Mtodos heredados cam1.setPatente( BX1515 ); de Vehculo cam1.setMarca( Iveco ); cam1.setCarga( 2000 ); } }
Franco Guidi Polanco 21
Una extensin al problema Suponga que se desea agregar al sistema un Camin con compartimientos, el cual posee patente, marca, carga mxima y una cantidad de compartimientos. Este camin es capaz de calcular la capacidad de carga por compartimiento (equivalente a la carga total, dividida por la cantidad de compartimientos). Adems provee un mtodo que retorna un String de descripcin, compuesto por Marca + Cantidad de compartimientos Qu se debe hacer?
Franco Guidi Polanco 22
Asientos
Autobs
Camin
Carga
Compartimientos
Franco Guidi Polanco
public class Ejemplo2 { public static void main( String arg[]){ CamionCompartimientos cam2 = new CamionCompartimientos(); cam2.setPatente( CX1818 ); Mtodos heredados cam2.setMarca( Ford ); de Vehculo cam2.setCarga( 2500 ); Mtodo heredado de Camin cam2.setCompartimientos( 5 ); System.out.println( cam2.getCargaCompartimiento() ); System.out.println( cam2.getdescripcin() ); } }
public class Persona { public String rut; public String nombre; public Persona() { rut = "00000000-0"; nombre = ""; } public void setRut(String r){ rut = r; } public String getRut(){ return rut; } public void setNombre(String n){ nombre = n; } public String getNombre(){ return nombre; } }
public class Alumno extends Persona { public String rolUCV; public Alumno() { rolUCV = 000000-0"; } public void setRolUCV(String r){ rolUCV = r; } public String getRolUCV(){ return rolUCV; }
public String quinSoy(){ return rut + nombre + rolUCV;
Veremos:
La implementacin de subclases en Java, cuando la sperclase posee variables de instancia privadas. La relacin entre constructores de sperclases y subclases. La relacin de las clases con la clase Object.
} }
Sperclase
Franco Guidi Polanco 27 Franco Guidi Polanco
Subclase
28
Miembros heredados (verdad parcial) Una subclase hereda de su sperclase (por el momento):
Variables de instancia pblicas Mtodos pblicos
Todos los anteriores pueden ser utilizados en la subclase como si hubieran sido declarados en ella .
29
30
Miembros no heredados: variables de instancia privadas Las variables privadas no son heredadas, por lo que no pueden aparecer en el cdigo de la subclase. Sin embargo se puede hacer uso indirecto de ellas en la subclase, a travs de los mtodos pblicos de manipulacin implementados en la respectiva sperclase.
Miembros no heredados: constructores Los constructores no son heredados, por lo que cada subclase debe tener su(s) propio(s) constructor(es). Sin embargo en los constructores se puede invocar al constructor de la superclase con la instruccin: super( lista parmetros ) La instruccin super debe ser la primera instruccin del constructor.
33 Franco Guidi Polanco 34
Esto s funciona
Franco Guidi Polanco
public class Alumno extends Persona { private String rolUCV; public Alumno() { super( 000000-0 , N/A rolUCV = 000000-0"; } );
public class Persona { private String rut; private String nombre; public Persona(String r, String n) { rut = r; nombre = n; } public void setRut(String r){ rut = r; } public String getRut(){ return rut; } public void setNombre(String n){ nombre = n; } public String getNombre(){ return nombre; } }
public class Alumno extends Persona { private String rolUCV; public Alumno(String r, String n, String l) { super( r, n ); rolUCV = l; } public void setRolUCV(String r){ rolUCV = r; } public String getRolUCV(){ return rolUCV; } public String quinSoy(){ return getRut() + getNombre() + rolUCV; } }
36
public void setRolUCV(String r){ rolUCV = r; } public String getRolUCV(){ return rolUCV; } public String quinSoy(){ return getRut() + getNombre() + rolUCV; } }
35
public class Alumno extends Persona { private String rolUCV; public Alumno() { rolUCV = 000000-0"; } public void setRolUCV(String r){ rolUCV = r; } public String getRolUCV(){ return rolUCV; } public String quinSoy(){ return getRut() + getNombre() + rolUCV; }
37
Herencia y constructores: la verdad total En Java toda clase extiende otra clase. Las clases que no declaran extender a otras, extienden a la clase Object (del package java.lang). Object es la superclase (directa o indirecta) de todas las clases. Todas las clases son subclases de Object o de otra subclase.
Por lo tanto: todos los constructores incluyen (explcitamente o no) una referencia al constructor de su superclase.
Franco Guidi Polanco 40
public Persona(String r, String n) { public Alumno() { rut = r; rolUCV = 000000-0"; nombre = n; } } public void setRut(String r){ public void setRolUCV(String r){ rut = r; } No compila rolUCV = r; } public String getRut(){ public String getRolUCV(){ public Alumno() { } return rut; } Java incluye automticamente return rolUCV; public void setNombre(String una referencia super(), pero a n){ super(); nombre = n; } public String quinSoy(){ un constructor inexistente en la rolUCV = 000000-0"; public String getNombre(){ return getRut() + getNombre() sperclase.nombre; } return + rolUCV; } } } }
Franco Guidi Polanco 39
Vehculo
Persona
Bien Raz
Camin
Alumno
Profesor
Casa
Negocio
Alumno pregrado
Alumno magster
Profesor hora
Veremos:
Un ejercicio de desarrollo de una jerarqua de herencia con variables de instancia privadas, y con referencias explcitas a constructor de la sperclase. La representacin de clases y jerarquas de herencia mediante diagramas de clases de UML.
Franco Guidi Polanco
Anlisis y diseo
Personaje Nombre de la clase! Variables de instancia! Mtodos y constructores! Guerrero
-arma: String +combatir(energ:int):String +Guerrero(nombre:String, energa:int, arma:String) -poder: String +encantar():String +Mago(nombre:String, poder:String) - nombre: String - energa: int +getNombre(): String +getEnergia(): int +alimentarse(energiaNueva:int) +consumirEnergia(gastoEnergia:int) +Personaje(nombre:String, energia:int)
Personaje
- nombre: String - energa: int +getNombre(): String +getEnergia(): int +alimentarse(energiaNueva:int) +consumirEnergia(gastoEnergia:int) +Personaje(nombre:String, energia:int)
Mago
46
Personaje
- nombre: String - energa: int +getNombre(): String +getEnergia(): int +alimentarse(energiaNueva:int) +consumirEnergia(gastoEnergia:int) +Personaje(nombre:String, energia:int)
Personaje
Guerrero
-arma: String +combatir(energ:int):String +Guerrero(nombre:String, energa:int, arma:String)
public Personaje(String nombre, int energia){ this.nombre = nombre; this.energia = energia; } public String getNombre(){ return nombre; } public int getEnergia(){ return energia; } public void alimentarse(int energiaNueva){ energia = energia + energiaNueva; } public void consumirEnergia(int gastoEnerg){ energia = energia - gastoEnerg; } }
Franco Guidi Polanco 47
public Guerrero(String nombre, int energia, String arma){ super(nombre, energia); this.arma = arma; } public String combatir(int energ){ actualizaEnergia( -1*energ ); return arma + energ; } }
Franco Guidi Polanco 48
Personaje
Mago
-poder: String +encantar(energ:int):String +Mago(nombre:String, poder:String)
public Mago(String nombre, String poder){ super(nombre, 100); this.poder = poder; } public String encantar(){ actualizaEnergia( -2 ); return poder; } }
Franco Guidi Polanco 49
50
Presentacin
Hemos visto:
Implementacin de jerarquas de herencia con variables de instancia pblicas y privadas e invocacin de constructores de sperclases mediante super. La clase Object como la sperclase de toda jerarqua de herencia en Java. La notacin del Diagrama de Clases de UML para clases y relaciones de herencia.
Veremos:
Tratamiento de variables que referencian subtipos. Sobreescritura de mtodos. Uso del operador instanceof para conocer el tipo de un objeto. Casting en jerarquas de herencia. Clases con miembros protegidos (protected).
Una variable de referencia puede referenciar objetos del mismo tipo de la variable (esto ya lo sabamos). Ejemplo: Persona p = new Persona(); Una variable de referencia puede referenciar objetos de cualquier subtipo de la variable. Ejemplos: Persona p = new Alumno(); Persona p = new Tesista();
En consecuencia, un arreglo de tipo Object puede almacenar cualquier tipo de objeto en sus posiciones:
Object[] arr = new Object[10]; arr[1] = new Persona(); arr[2] = new Tesista(); arr[3] = new Lavadora();
53 Franco Guidi Polanco 54
Reconocimiento de clases: operador instanceof El operador instanceof permite reconocer la clase a la que pertenece un objeto referenciado desde una variable determinada. Formato: NombreVar instanceof NombreClase Ejemplo:
if( pers instanceof Persona ) System.out.println( La variable pers referencia a una Persona ); else System.out.println( La variable pers no referencia a una Persona );
Una variable de referencia de un determinado tipo NO puede referenciar objetos de un spertipo. Por lo anterior, las siguientes asignaciones NO son vlidas: Alumno a = new Persona(); Tesista t = new Alumno(); Tesista t = new Persona();
55
56
Operador instanceof y herencia Todo objeto es instancia de la clase a la que pertenece, como tambin instancia de su superclase.
Persona Electrodomstico
Lavadora
Profesor
Alumno
Sobreescritura de mtodos
Persona personas = new Persona[100]; // Supongamos que aqu se ingresan // al arreglo Personas, Alumnos // y Tesistas.
Un mtodo declarado e implementado en una sperclase puede ser reimplementado en una subclase. Esto se denomina sobreescritura de mtodos. Conceptualmente significa que la subclase realiza la misma operacin de la sper clase, pero de un modo distinto. Esto es un caso de polimorfismo.
public class Persona { private String rut; private String nombre; public String getRut(){ return rut; } public String getNombre(){ return nombre; } public String identificarse(){ return rut + nombre; } //otros miembros de la clase }
59 Franco Guidi Polanco
public class Alumno extends Persona { private String carrera; public String identificarse(){ return getRut() + getNombre() + carrera; } //otros miembros de la clase }
60
//Aqu se muestra la cantidad de tesistas cantidadTesistas = 0; for(int i=0; i< personas.length; i++) if( personas[i] instanceof Tesista ) cantidadTesistas++; System.out.println( Hay + cantidadTesistas + tesistas);
Franco Guidi Polanco
100Matas
public String identificarse(){ return rut + nombre; }
100
Matas
getRut() getNombre()
public Alumno(String r, String n, String c){ super(r,n); carrera = c; } public String identificarse(){ return getRut() + getNombre() + carrera; } }
identificarse()
100MatasInd
b
Franco Guidi Polanco
62
Sobreescritura de mtodos
public class Persona { private String rut, nombre; public Persona(String r, String n){ rut = r; nombre = n; } public String getRut(){ return rut;} public String getNombre(){ return nombre;} public String identificarse(){ return rut + nombre; } } public class Alumno extends Persona { private String carrera; public Alumno(String r, String n, String c){ super(r,n); carrera = c; } public String identificarse(){ public String identificarse(){ return getRut() + getNombre() return getRut() + getNombre() + carrera; + carrera; } } }
100MatasInd
Java resuelve en tiempo de ejecucin la asociacin entre la variable de referencia y el mtodo que debe invocar, en funcin del objeto que se encuentre referenciado en ella.
Franco Guidi Polanco 63
100MatasInd
64
Sobreescritura de mtodos
Persona a = new Alumno( 100 , Matas , Ind ); System.out.println( a.identificarse() );
El compilador Java es responsable de verificar que el mtodo pertenezca al tipo de dato declarado por la variable. El intrprete Java es responsable de identificar y ejecutar la implementacin del mtodo correspondiente al tipo de objeto referenciado en el momento por la variable.
65
66
Casting
public class Persona { private String rut; private String nombre; public setDatos(String r, String n) { rut = r; nombre = n; } public String getRut(){ return rut; } public String getNombre(){ return nombre; } } public class Alumno extends Persona { private String carrera; public String matricularse( String c){ carrera = c; } }
Esto funciona?
Persona c = new Alumno(); c.setDatos( 1000-2, Luis); c.matricularse( Comercial );
Error: el compilador determina que este mtodo no pertenece a Persona. Sin embargo la variable contiene referencia a un Alumno, que es un tipo de Persona (y que posee este mtodo).
Es necesario introducir un casting para indicar al compilador que el objeto referenciado en la variable es efectivamente una instancia de Alumno: Persona c = new Alumno(); c.setDatos( 1000-2, Luis); ( (Alumno)c ).matricularse( Industrial );
Franco Guidi Polanco 68
67
Casting El casting no convierte objetos, simplemente explicita el tipo de objeto referenciado en una variable.
Persona a = new Profesor(); Profesor b = a; // ERROR
Miembros protegidos de una clase El modificador de visibilidad protected, permite declarar visibilidad protegida en variables de instancia y mtodos. Los miembros de una clase con visibilidad protegida son slo accesibles desde la misma clase o desde cualquier subclase de ella (no son accesibles desde otras clases).
Persona
Profesor
Alumno
Persona a = new Persona(); Profesor b = (Profesor) a; // ERROR Alumno c = (Alumno) a; // ERROR Alumno a = new Alumno(); Profesor b = (Profesor) a; // ERROR
69
70
Miembros protegidos de una clase Por lo tanto, una subclase hereda de su superclase:
Variables de instancia protegidas y pblicas Mtodos protegidos y pblicos
71
72
Identificacin de superclases
Contexto: se est desarrollando una aplicacin que trabaja con CDs, DVDs y discos de vinilo. Problema: se establece que a pesar de tener sus propios atributos, todos ellos disponen de cdigo, sello discogrfico y autor. Se desea evitar duplicidad de cdigo. Decisin: se determina la conveniencia de crear la clase ProductoMusical, que agrupa las propiedades comunes de los tres tipos de productos.
CD
DVD
Vinilo
Clases abstractas
En el ejemplo anterior la clase ProductoMusical es abstracta (no representa entidades presentes en el dominio). Esta condicin se explicita en el diseo, declarando la clase como abstracta. ProductoMusical {abstract} cdigo sello autor
public abstract class ProductoMusical { private int cdigo; private String sello; ... }
Clases abstractas Otro ejemplo: un software trabaja con distintas figuras geomtricas, todas ellas polgonos, con algunas propiedades en comn (ej. cantidad de lados).
Polgono
CD
DVD
Vinilo
Una clase abstracta no puede ser instanciada, ha sido diseada slo para ser extendida.
Franco Guidi Polanco 75 Franco Guidi Polanco 76
Clases abstractas
public abstract class Poligono { protected int lados; public void setLados(int l){ lados = l; } ... }
Mtodos abstractos
Supongamos que en el ejemplo anterior todos los polgonos deben proveer un mtodo de clculo de rea. Conflicto de fuerzas en diseo:
Todos los polgonos deben proveer el mtodo, por lo tanto debiese aparecer a nivel de la superclase Polgono. La operacin del mtodo depende de cada polgono concreto (ej. rea de cuagrado: lado2, rea de tringulo base * altura /2, etc.), por lo tanto no puede establecerse una lgica comn a nivel de superclase.
Polgono
Polgono
public class Cuadrado extends Poligono { private int longitud; public void setLongitud(double l) { longitud = l; } ... }
Franco Guidi Polanco 77
Mtodos abstractos Un mtodo abstracto es un mtodo que se declara en una superclase, pero sin proveer implementacin. La implementacin de un mtodo abstracto se difiere para sus subclases. Una clase que declara uno o ms mtodos abstractos es necesariamente abstracta (y debe ser declarada como tal). Si una subclase no provee implementacin para un mtodo abstracto que hereda de su superclase, es necesariamente abstracta (y debe ser declarada como tal).
Franco Guidi Polanco 79
Mtodos abstractos
public abstract class Poligono { protected int lados; public int setLados(int l){ lados = l; } public abstract double getArea(); ... } public class Cuadrado extends Poligono { private double longitud; public void setLongitud(double l) { longitud = l; } public double getArea(){ return longitud*longitud; } ... }
Franco Guidi Polanco
Polgono
80 80
81