Está en la página 1de 21

Herencia

 Es la derivación de una clase a partir de otra


existente.
 El objetivo es la reutilización del software
POO en Java IV: Herencia desarrollado.
(Parte 1)

Franco Guidi Polanco


Escuela de Ingeniería Industrial
Pontificia Universidad Católica de Valparaíso, Chile Herencia
fguidi@ucv.cl

Actualización: 22 de Agosto de 2011


Franco Guidi Polanco 2

Súperclases y subclases Súperclases y subclases

 La clase de la cual se deriva otra clase se denomina  La subclases heredan propiedades de su súperclase.
clase base, súperclase o clase padre.  Una subclase, respecto de su súperclase:
  Agrega nuevas propiedades
 Una clase derivada de una súperclase recibe también   Modifica propiedades heredadas.
el nombre de subclase o clase hija.
Patente
Marca
Súperclase -----
Vehículo Clase base Avanza
Clase padre Vehículo

Subclase
Camión Clase derivada Patente
Clase hija Camión Marca
Carga máxima
-----
 La herencia aplica en relaciones de naturaleza B es un Avanza
tipo de A Activa tolva

Franco Guidi Polanco 3 Franco Guidi Polanco 4


Herencia simple Herencia múltiple

 Una clase es subclase de una única súperclase.  Una clase es subclase de más de una súperclase.

Vehículos Vehículos
terrestres acuáticos

Vehículo
Vehículos
anfibios

Camión
 Java no soporta la herencia múltiple.

Franco Guidi Polanco 5 Franco Guidi Polanco 6

Jerarquías de Herencia Ejemplo (1/2)

 La herencia organiza clases bases y derivadas en  Determinar si en las siguientes situaciones existe una
jerarquías de clases. relación de herencia entre las clases (indicadas en negrita):

Caso 1 Caso 2 Caso 3


 Rut, nombre
Persona
 set y get nombre Todo Los Bienes raíces Un Camión tiene
Electrodoméstico se tienen un Rol de Patente. Un Conductor
enciende y apaga. El identificación. Una tiene un camión
Horno microondas Casa tiene también un conducido.
+ Universidad Profesor + Especialidad además abre y cierra su Jefe de hogar y un
Alumno
+ set y get Universidad + set y get Especialidad puerta. Negocio tiene una
Patente comercial

+ Carrera
+ set y get Carrera

Franco Guidi Polanco


Alumno
pregrado
Alumno + Tesis
magíster + set y get Tesis
Profesor + Horas
hora + set y get Horas

7
Electrodoméstico

Horno Microondas

Franco Guidi Polanco


Casa
Bien Raíz

Negocio X 8
Ejemplo (2/2) Implementación de jerarquías de herencia

 Determinar si en las siguientes situaciones existe una  Para crear una subclase a partir de una superclase, en
relación de herencia entre las clases (indicadas en negrita): Java la subclase debe declararse:
Caso 4 Caso 5 Caso 6
Los Archivos Un Avión tiene Una Gaviota vuela.
Multimediales pueden Fuselaje, Alas y Una Abeja vuela y
public class NombreSubclase extends NombreSuperclase
ser Imágenes o Motores. además tiene aguijón.
Música. Las imágenes
pueden ser a Color o
Blanco y Negro.  Ejemplo:

X X
Multimedia
Persona
public class Alumno extends Persona
Música Imagen

Color B/N Alumno


Franco Guidi Polanco 9 Franco Guidi Polanco 10

Implementación de jerarquías de herencia:


Implementación de jerarquías de herencia
ejemplo

 Implementar las clases Persona y Alumno, de


acuerdo con lo siguiente: public class Persona { public class Alumno extends Persona {

public String rut; public String rolUCV;


Atributos: Operaciones: public String nombre;
Persona - RUT -set y get RUT
public Persona() {
public Alumno() {
rolUCV = 000000-0";
- Nombre - set y get Nombre rut = "00000000-0"; }
nombre = ""; } public void setRolUCV(String r){
public void setRut(String r){ rolUCV = r;
rut = r; } }
Atributos: Operaciones: public String getRut(){ public String getRolUCV(){
Alumno - RUT -set y get RUT return rut; }
public void setNombre(String n){ }
return rolUCV;

- Nombre - set y get Nombre nombre = n; } public String quiénSoy(){


- Rol UCV - set y get Rol UCV public String getNombre(){ return rut + nombre + rolUCV;
return nombre; } }
} }
 NOTA: Supondremos, por el momento, todos los
miembros públicos. Súperclase Subclase
Franco Guidi Polanco 11 Franco Guidi Polanco 12
Miembros heredados (verdad parcial)

 Una subclase hereda de su súperclase (por el


momento):
  Variables de instancia públicas
  Métodos públicos POO en Java IV: Herencia
(Parte 2)
 Todos los anteriores pueden ser utilizados en la
subclase como si hubieran sido declarados en Franco Guidi Polanco
ella . Escuela de Ingeniería Industrial
Pontificia Universidad Católica de Valparaíso, Chile
fguidi@ucv.cl

Actualización: 22 de Agosto de 2011


Franco Guidi Polanco 13

Presentación Ejercicio

 Hemos visto: Implemente las clases Vehículo, Autobús y


  La definición de herencia (y la relación subyacente entre Camión, dados los siguientes antecedentes:
“tipos”)  Todo Vehículo tiene patente y marca.
  El concepto de súperclase y subclase
 Los Autobuses y los Camiones son Vehículos.
  La definición de jerarquía de herencia
 Todo Autobús tiene cantidad de asientos.
  La declaración de una subclase en Java
  La extensión de clases que poseen miembros públicos.  Todo Camión tiene carga en toneladas.
 Veremos:
  Un problema de diseño e implementación con herencia,
utilizando miembros públicos.
  Se desarrollará una extensión del sistema desarrollado
en el problema.

Franco Guidi Polanco 15 Franco Guidi Polanco 16


Análisis Implementación

 Jerarquía de clases  Vehículo:


public class Vehiculo{

public String patente;


Vehículo  Patente, marca public String marca;

public void setPatente(String p){


patente = p;
}
public String setMarca(String m){
marca = m;
 Asientos Autobús Camión  Carga }
public String getPatente(){
return patente;
}
public String getMarca(){
return marca;
}
}
Franco Guidi Polanco 17 Franco Guidi Polanco 18

Implementación Implementación

 Autobús  Camión:

public class Autobus extends Vehiculo{ public class Camion extends Vehiculo{

public int asientos; public int carga;

public void setAsientos(int a){ public void setCarga(int c){


asientos = a; carga = c;
} }
public int getAsientos(){ public int getCarga(){
return asientos; return carga;
} }
} }

Franco Guidi Polanco 19 Franco Guidi Polanco 20


Uso de las clases desarrolladas Una extensión al problema

 Entonces una aplicación podría realizar lo  Suponga que se desea agregar al sistema un
siguiente: Camión con compartimientos, el cual posee
public class Ejemplo {
patente, marca, carga máxima y una cantidad de
public static void main( String arg[]){ compartimientos. Este camión es capaz de calcular

Autobus bus1 = new Autobus();
la capacidad de carga por compartimiento
bus1.setPatente( “AX1313” ); Métodos heredados (equivalente a la carga total, dividida por la
bus1.setMarca( “Mercedes” ); de Vehículo
bus1.setAsientos( 40 ); cantidad de compartimientos). Además provee un
… método que retorna un String de descripción,
Camion cam1 = new Camion();
cam1.setPatente( “BX1515” ); Métodos heredados compuesto por Marca + Cantidad de
cam1.setMarca( “Iveco” ); de Vehículo
compartimientos
cam1.setCarga( 2000 );

}
} ¿Qué se debe hacer?
Franco Guidi Polanco 21 Franco Guidi Polanco 22

Análisis Implementación

 El Camión con compartimientos es una  Camión con compartimientos:


subclase de Camión. public class CamionCompartimientos extends Camion{

public int compartimientos=1;


Vehículo  Patente, marca
public void setCompartimientos(int c){
compartimientos = c;
} carga: es
public int getCompartimientos(){ heredado
return compartimientos; (desde
} Camión)
 Asientos Autobús Camión  Carga
public int getCargaCompartimiento(){
return carga/compartimientos;
} marca: es
public String getDescripción(){ heredado
return marca + compartimientos;
 Compartimientos Camión con }
(desde
Vehículo)
compartimientos }
Franco Guidi Polanco 23 Franco Guidi Polanco 24
Uso de la nueva clase

public class Ejemplo2 {


public static void main( String arg[]){

CamionCompartimientos cam2 = new CamionCompartimientos(); POO en Java IV: Herencia
cam2.setPatente( “CX1818” );
cam2.setMarca( “Ford” );
Métodos heredados
de Vehículo (Parte 3)
cam2.setCarga( 2500 ); Método heredado de Camión
cam2.setCompartimientos( 5 );
System.out.println( cam2.getCargaCompartimiento() ); Franco Guidi Polanco
System.out.println( cam2.getdescripción() ); Escuela de Ingeniería Industrial

Pontificia Universidad Católica de Valparaíso, Chile
} fguidi@ucv.cl
}

Actualización: 22 de Agosto de 2011


Franco Guidi Polanco 25

Repaso: extensión de una clase con miembros


Presentación
públicos
 Hemos visto:
  Los conceptos funamentales asociados a la herencia. public class Persona { public class Alumno extends Persona {
  La implementación de subclases en Java, en presencia public String rut; public String rolUCV;
de miembros públicos en la súperclase. public String nombre;
public Alumno() {
 Veremos: public Persona() {
rut = "00000000-0"; }
rolUCV = 000000-0";

  La implementación de subclases en Java, cuando la nombre = ""; } public void setRolUCV(String r){
public void setRut(String r){ rolUCV = r;
súperclase posee variables de instancia privadas. rut = r; } }
public String getRut(){ public String getRolUCV(){
  La relación entre constructores de súperclases y return rut; } return rolUCV;
subclases. public void setNombre(String n){
nombre = n; }
}
public String quiénSoy(){
  La relación de las clases con la clase Object. public String getNombre(){
}
return rut + nombre + rolUCV;
return nombre; }
} }

Súperclase Subclase
Franco Guidi Polanco 27 Franco Guidi Polanco 28
Miembros heredados (verdad parcial) Miembros no heredados

 Una subclase hereda de su súperclase (por el  Una subclase no hereda:


momento):   Propiedades privadas
  Variables de instancia públicas   Constructores
  Métodos públicos
 Los miembros no heredados no pueden aparecer
en el código de la subclase.
 Todos los anteriores pueden ser utilizados en la
subclase como si hubieran sido declarados en
ella .

Franco Guidi Polanco 29 Franco Guidi Polanco 30

Miembros no heredados: variables de instancia Miembros no heredados: variables de instancia


privadas privadas
 No funciona:  Las variables privadas no son heredadas, por lo
public class Persona { public class Alumno extends Persona {
que no pueden aparecer en el código de la
private String rut; private String rolUCV;
subclase.
private String nombre;
public Alumno() {
public Persona() { rolUCV = 000000-0";
rut = "00000000-0"; }  Sin embargo se puede hacer uso indirecto de
nombre = ""; }
public void setRut(String r){
public void setRolUCV(String r){
rolUCV = r; ellas en la subclase, a través de los métodos
rut = r; }
public String getRut(){
}
public String getRolUCV(){ públicos de manipulación implementados en la
return rut; }
public void setNombre(String n){ }
return rolUCV;
respectiva súperclase.
nombre = n; } public String quiénSoy(){
public String getNombre(){ return rut + nombre + rolUCV;
return nombre; } }
} }

Error: no pueden ser accesadas directamente


(No compila)
Franco Guidi Polanco 31 Franco Guidi Polanco 32
Miembros no heredados: variables de instancia
Miembros no heredados: constructores
privadas
 Ejemplo correcto:  Los constructores no son heredados, por lo que
public class Persona { public class Alumno extends Persona {
cada subclase debe tener su(s) propio(s)
private String rut; private String rolUCV;
constructor(es).
private String nombre;
public Alumno() {  Sin embargo en los constructores se puede invocar
public Persona() {
rut = "00000000-0"; }
rolUCV = 000000-0";
al constructor de la superclase con la instrucción:
nombre = ""; } public void setRolUCV(String r){
public void setRut(String r){ rolUCV = r; }
rut = r; } public String getRolUCV(){
public String getRut(){ return rolUCV; } super( lista parámetros )
return rut; }
public void setNombre(String n){ public String quiénSoy(){
nombre = n; } return getRut() + getNombre()
public String getNombre(){
return nombre; } }
+ rolUCV;
 La instrucción super debe ser la primera
} } instrucción del constructor.
Esto sí funciona
Franco Guidi Polanco 33 Franco Guidi Polanco 34

Uso de super en constructores Uso de super en constructores

 Ejemplo 1:  Ejemplo 2:
public class Persona { public class Alumno extends Persona { public class Persona { public class Alumno extends Persona {

private String rut; private String rolUCV; private String rut; private String rolUCV;
private String nombre; private String nombre;
public Alumno() { public Alumno(String r, String n,
public Persona(String r, String n) { super( 000000-0 , N/A ); public Persona(String r, String n) { String l) {
rut = r; rolUCV = 000000-0"; rut = r; super( r, n );
nombre = n; } nombre = n; rolUCV = l;
} } }
public void setRolUCV(String r){ public void setRolUCV(String r){
public void setRut(String r){ rolUCV = r; } public void setRut(String r){ rolUCV = r;
rut = r; } public String getRolUCV(){ rut = r; } }
public String getRut(){ return rolUCV; } public String getRut(){ public String getRolUCV(){
return rut; } return rut; } return rolUCV;
public void setNombre(String n){ public String quiénSoy(){ public void setNombre(String n){ }
nombre = n; } return getRut() + getNombre() nombre = n; } public String quiénSoy(){
public String getNombre(){ + rolUCV; public String getNombre(){ return getRut() + getNombre()
return nombre; } } return nombre; } + rolUCV;
} } } }
}

Franco Guidi Polanco 35 Franco Guidi Polanco 36


Herencia y constructores: la verdad parcial Herencia y constructores

 Todo subclase debe incluir una referencia super a algún  Dos clases equivalentes:
constructor de la superclase.
public class Alumno extends public class Alumno extends
Persona { Persona {
 Si no se incluye la referencia super, Java incluye private String rolUCV; private String rolUCV;
automáticamente una referencia al constructor sin
public Alumno() { public Alumno() {
parámetros de la superclase. Es decir incluye: super(); rolUCV = 000000-0";
super() }
rolUCV = 000000-0"; }

public void setRolUCV(String r){ public void setRolUCV(String r){


 Notar que se produce un error cuando no existe un rolUCV = r; }
public String getRolUCV(){
rolUCV = r; }
public String getRolUCV(){
constructor sin parámetros en la superclase y se omite la return rolUCV; } return rolUCV; }
referencia super en la subclase ¿por qué? public String quiénSoy(){ public String quiénSoy(){
return getRut() + getNombre() return getRut() + getNombre()
+ rolUCV; + rolUCV;
} }
} }

Franco Guidi Polanco 37 Franco Guidi Polanco 38

Herencia y constructores: ¡Atención! Herencia y constructores: la verdad total

 ¿Qué pasa en el siguiente caso?  En Java toda clase extiende otra clase.
public class Persona { public class Alumno extends
 Las clases que no declaran extender a otras,
Persona { extienden a la clase Object (del package
private String rut;
private String nombre; private String rolUCV; java.lang).
public Persona(String r, String n) {
rut = r;
public Alumno() {
rolUCV = 000000-0";
 Object es la superclase (directa o indirecta) de
nombre = n; } todas las clases.
}
public void setRut(String r){
rut = r; } No compila
public void setRolUCV(String r){
rolUCV = r; }
 Todas las clases son subclases de Object o de otra
public String getRut(){
Java incluyerut;
return automáticamente
} public public String getRolUCV(){
Alumno() { subclase.
return rolUCV; }
public
una super(), pero a n){ super();
void setNombre(String
referencia
nombre = n; } public String quiénSoy(){
un constructor inexistente en la rolUCV = 000000-0";
public String getNombre(){
súperclase.
return getRut() + getNombre() Por lo tanto: todos los constructores incluyen
return nombre; } } + rolUCV;
(explícitamente o no) una referencia al constructor de su
}
} } superclase.
Franco Guidi Polanco 39 Franco Guidi Polanco 40
Herencia y constructores: la verdad total

Object

Vehículo Persona Bien Raíz POO en Java IV: Herencia


(Parte 4)
Camión Casa Negocio
Alumno Profesor
Franco Guidi Polanco
Escuela de Ingeniería Industrial
Pontificia Universidad Católica de Valparaíso, Chile
fguidi@ucv.cl
Alumno Alumno Profesor
pregrado magíster hora

Actualización: 22 de Agosto de 2011


Franco Guidi Polanco 41

Presentación Ejercicio: Implementar las siguientes clases

 Hemos visto:   Un videojuego tiene Personajes. Cada personaje tiene un nombre


(String) y un nivel propio de energía (int). Además implementan el
  Implementación de jerarquías de herencia con variables método alimentarse, que recibe por parámetro una cantidad de energía
de instancia públicas y privadas. (int) con el que incrementa el nivel propio de energía. Los personajes
  Invocación de constructores de súperclases mediante pueden ser:
  Guerreros: tienen además un arma (String). Al momento de la
super.
instanciación reciben su nombre, arma y nivel propio de energía
  La clase Object como la súperclase de toda jerarquía de inicial. Los guerreros tienen un método combatir que recibe por
herencia en Java. parámetro la cantidad de energía a gastar en el ataque, la cual es
descontada de su nivel propio de energía. El método combatir retorna
 Veremos: el arma y la cantidad de energía del ataque concatenados.
  Un ejercicio de desarrollo de una jerarquía de herencia   Magos: tienen además un poder (String). Al momento de la
con variables de instancia privadas, y con referencias instanciación reciben su nombre y poder. Los magos son siempre
creados con un nivel propio de energía igual a 100. Proveen un
explícitas a constructor de la súperclase.
método encantar, que disminuye en 2 unidades el nivel propio de
  La representación de clases y jerarquías de herencia energía y que retorna el poder del mago.
mediante diagramas de clases de UML.
Franco Guidi Polanco 43 Franco Guidi Polanco 44
Análisis y diseño Análisis y diseño

 La clase Personaje:


Personaje
- nombre: String
Nombre de la - energía: int

Personaje clase!
+getNombre(): String
+getEnergia(): int
Visibilidad
+alimentarse(energiaNueva:int)
privada (-)! - nombre: String Variables de +consumirEnergia(gastoEnergia:int)
- energía: int instancia! +Personaje(nombre:String, energia:int)
Visibilidad
pública (+)! +getNombre(): String Métodos y
+getEnergia(): int constructores!
+alimentarse(energiaNueva:int)
+consumirEnergia(gastoEnergia:int) Guerrero Mago
+Personaje(nombre:String, energia:int) -arma: String -poder: String
+combatir(energ:int):String
+encantar():String
+Guerrero(nombre:String, energía:int,
+Mago(nombre:String, poder:String)
arma:String)
Los constructores van subrayados!

Franco Guidi Polanco 45 Franco Guidi Polanco 46

Personaje
Implementación Personaje Implementación
- nombre: String
 Clase Personaje: - energía: int
 Clase Guerrero:
+getNombre(): String Guerrero
public class Personaje{ +getEnergia(): int
+alimentarse(energiaNueva:int) -arma: String
private String nombre; +consumirEnergia(gastoEnergia:int)
+Personaje(nombre:String, energia:int) +combatir(energ:int):String
private int energia; +Guerrero(nombre:String,
energía:int, arma:String)
public Personaje(String nombre, int energia){ public class Guerrero extends Personaje{
this.nombre = nombre;
private String arma;
this.energia = energia; }
public String getNombre(){ public Guerrero(String nombre, int energia, String arma){
return nombre; } super(nombre, energia);
this.arma = arma;
public int getEnergia(){ }
return energia; } public String combatir(int energ){
public void alimentarse(int energiaNueva){ actualizaEnergia( -1*energ );
energia = energia + energiaNueva; } return arma + energ;
}
public void consumirEnergia(int gastoEnerg){
energia = energia - gastoEnerg; } }
}
Franco Guidi Polanco 47 Franco Guidi Polanco 48
Personaje
Implementación Uso de las clases

 Clase Mago: Mago  Ejemplo:


-poder: String

+encantar(energ:int):String
+Mago(nombre:String, poder:String)
public class Mago extends Personaje{ Guerrero g1 = new Guerrero(“Alfa”, 50, “Burbujitas de jabón”);
g1.combatir( 2 );
private String poder; System.out.println( “El nivel de energía de ” + g1.getNombre()
+ “ es ” + g1.getEnergia() );
public Mago(String nombre, String poder){
super(nombre, 100); …
this.poder = poder;
} Mago m1 = new Mago( “Harry”, “Quemar” );
public String encantar(){ m1.encantar();
actualizaEnergia( -2 ); System.out.println( “El nivel de energía de ” + m1.getNombre()
return poder; + “ es ” + m1.getEnergia() );
}

}

Franco Guidi Polanco 49 Franco Guidi Polanco 50

Presentación

 Hemos visto:
  Implementación de jerarquías de herencia con variables de
instancia públicas y privadas e invocación de constructores de
súperclases mediante super.
  La clase Object como la súperclase de toda jerarquía de herencia
POO en Java IV: Herencia en Java.
(Parte 5)   La notación del Diagrama de Clases de UML para clases y relaciones
de herencia.

Franco Guidi Polanco  Veremos:


  Tratamiento de variables que referencian subtipos.
Escuela de Ingeniería Industrial
Pontificia Universidad Católica de Valparaíso, Chile   Sobreescritura de métodos.
fguidi@ucv.cl   Uso del operador instanceof para conocer el tipo de un objeto.
  Casting en jerarquías de herencia.
  Clases con miembros protegidos (protected).
Actualización: 22 de Agosto de 2011
Franco Guidi Polanco 52
Referencias, tipos y subtipos Referencias, tipos y subtipos

 Una variable de referencia puede  Dado que toda clase es subclase directa o indirecta de la
Persona referenciar objetos del mismo tipo de clase Object, una variable de este tipo puede referenciar
la variable (esto ya lo sabíamos). objetos de cualquier tipo. Ejemplos:
Ejemplo:
Object o = new Persona();
Alumno Object o = new Tesista();
Persona p = new Persona();
Object o = new Lavadora();

Tesista  Una variable de referencia puede  En consecuencia, un arreglo de tipo Object puede
referenciar objetos de cualquier almacenar cualquier tipo de objeto en sus posiciones:
subtipo de la variable. Ejemplos:
Object[] arr = new Object[10];
Persona p = new Alumno(); arr[1] = new Persona();
Persona p = new Tesista(); arr[2] = new Tesista();
arr[3] = new Lavadora();

Franco Guidi Polanco 53 Franco Guidi Polanco 54

Referencias, tipos y subtipos Reconocimiento de clases: operador instanceof

 Una variable de referencia de un


Persona determinado tipo NO puede referenciar
 El operador instanceof permite reconocer la clase a
objetos de un súpertipo. la que pertenece un objeto referenciado desde una
variable determinada.
Alumno  Por lo anterior, las siguientes  Formato:
asignaciones NO son válidas: NombreVar instanceof NombreClase
 Ejemplo:
Tesista Alumno a = new Persona();
if( pers instanceof Persona )
Tesista t = new Alumno();
System.out.println( La variable pers referencia a una Persona );
Tesista t = new Persona();
else
System.out.println( La variable pers no referencia a una Persona );

Franco Guidi Polanco 55 Franco Guidi Polanco 56


Operador instanceof y herencia Operador instanceof: ejemplo

 Suponer: Persona p1 =null:


 Todo objeto es instancia de la clase a la que
Profesor p2 = new Profesor();
pertenece, como también instancia de su
Alumno p3 = new Alumno();
superclase.
Persona if( p1 instanceof Persona ) --> false!

Electrodoméstico if( p2 instanceof Profesor ) --> true!


Profesor Alumno if( p2 instanceof Persona ) --> true!
Un objeto de la clase lavadora es
if( p2 instanceof Alumno ) --> false!
también un electrodoméstico
Lavadora
if( p3 instanceof Alumno ) --> true!
if( p3 instanceof Persona ) --> true!
if( p3 instanceof Profesor ) --> false!

Franco Guidi Polanco 57 Franco Guidi Polanco 58

Operador instanceof: ejemplo Sobreescritura de métodos

Persona  Un método declarado e implementado en una súperclase


puede ser reimplementado en una subclase. Esto se
denomina sobreescritura de métodos.
Alumno  Conceptualmente significa que la subclase realiza la misma
Persona personas = new Persona[100];
operación de la súper clase, pero de un modo distinto.
// Supongamos que aquí se ingresan  Esto es un caso de polimorfismo.
// al arreglo Personas, Alumnos
// y Tesistas. Tesista public class Persona {
private String rut;
public class Alumno extends
Persona {

private String nombre;
public String getRut(){ private String carrera;
//Aquí se muestra la cantidad de tesistas return rut; }
cantidadTesistas = 0; public String getNombre(){ public String identificarse(){
for(int i=0; i< personas.length; i++) return nombre; } return getRut() + getNombre()
public String identificarse(){ + carrera;
if( personas[i] instanceof Tesista ) return rut + nombre; }
cantidadTesistas++; }
System.out.println( “Hay” + cantidadTesistas + “ tesistas”); //otros miembros de la clase… //otros miembros de la clase…
… } }

Franco Guidi Polanco 59 Franco Guidi Polanco 60


Sobreescritura de métodos ¿Qué ocurre en las siguientes situaciones?

 Consideremos estas clases en los siguientes Persona a = new Persona( 100 , Matías );
System.out.println( a.identificarse() ); 100Matías
ejemplos:
public class Persona { public class Alumno extends 100 Matías public String identificarse(){
Persona { return rut + nombre;
private String rut, nombre; getRut() }
private String carrera;
public Persona(String r, String n){ getNombre()

a
rut = r; public Alumno(String r, String
nombre = n; n, String c){
identificarse()
} super(r,n);
carrera = c;
Alumno b = new Alumno( 100 , Matías , Ind );
public String getRut(){
return rut;
}
System.out.println( b.identificarse() ); 100MatíasInd
} public String identificarse(){
public String getNombre(){ return getRut() + getNombre() public String identificarse(){
return nombre; + carrera; 100 Matías Ind return getRut() +
} } getNombre() +
public String identificarse(){ getRut() carrera;
}
return rut + nombre; }
getNombre()
b
}
}
identificarse()
Franco Guidi Polanco 61 Franco Guidi Polanco 62

¿Qué ocurre en la siguiente situación? Sobreescritura de métodos


public class Persona { public class Alumno extends
Persona a = new Alumno( 100 , Matías , Ind ); private String rut, nombre; Persona {
System.out.println( a.identificarse() ); 100MatíasInd public Persona(String r, String n){
rut = r; nombre = n;
private String carrera;
public Alumno(String r, String
} n, String c){
public String getRut(){ return rut;} super(r,n); carrera = c;
public String identificarse(){ public String getNombre(){ }
100 Matías Ind return getRut() +
return nombre;} public
public String
String identificarse(){
identificarse(){
public String identificarse(){ return
return getRut()
getRut() ++ getNombre()
getNombre()
getRut() getNombre() + return rut + nombre; + carrera;
+ carrera;
carrera; } }}
getNombre() } } }

a identificarse()

Persona a = new Alumno( 100 , Matías , Ind );


Java resuelve en tiempo de ejecución la asociación entre la System.out.println( a.identificarse() ); 100MatíasInd
variable de referencia y el método que debe invocar, en
función del objeto que se encuentre referenciado en ella.

Franco Guidi Polanco 63 Franco Guidi Polanco 64


Sobreescritura de métodos Herencia y acceso a miembros de una clase
public class Persona { public class Alumno extends
Persona a = new Alumno( 100 , Matías , Ind ); private String rut; Persona {
System.out.println( a.identificarse() ); private String nombre;
public setDatos(String r, String n) { private String carrera;
rut = r;
nombre = n; } public String matricularse(
 El compilador Java es responsable de verificar que public String getRut(){
return rut; } carrera = c;
String c){

el método pertenezca al tipo de dato declarado por public String getNombre(){


return nombre; }
}

la variable. } }

 El intérprete Java es responsable de identificar y


  Esto debe funcionar:
ejecutar la implementación del método
correspondiente al tipo de objeto referenciado en Persona a = new Persona();
a.setDatos( “1000-2”, “Luis”);
el momento por la variable.
Alumno b = new Alumno();
b.setDatos( “2000-3”, “Pamela” );
b.matricularse( “Industrial” );

Franco Guidi Polanco 65 Franco Guidi Polanco 66

Herencia y acceso a miembros de una clase Casting


public class Persona { public class Alumno extends public class Persona { public class Alumno extends
private String rut; Persona { private String rut; Persona {
private String nombre; private String nombre;
public setDatos(String r, String n) { private String carrera; public setDatos(String r, String n) { private String carrera;
rut = r; rut = r;
nombre = n; } public String matricularse( nombre = n; } public String matricularse(
public String getRut(){ String c){ public String getRut(){ String c){
return rut; } carrera = c; return rut; } carrera = c;
public String getNombre(){ } public String getNombre(){ }
return nombre; } return nombre; }
} } } }

  ¿Esto funciona? Error: el compilador


 Es necesario introducir un casting para indicar al
determina que este método compilador que el objeto referenciado en la variable es
Persona c = new Alumno(); no pertenece a Persona. Sin efectivamente una instancia de Alumno:
c.setDatos( “1000-2”, “Luis”); embargo la variable contiene
c.matricularse( “Comercial” ); referencia a un Alumno, que es
un tipo de Persona (y que posee Persona c = new Alumno();
este método). c.setDatos( “1000-2”, “Luis”);
( (Alumno)c ).matricularse( “Industrial” );
Franco Guidi Polanco 67 Franco Guidi Polanco 68
Casting Miembros protegidos de una clase

 El casting no convierte objetos, simplemente  El modificador de visibilidad protected, permite
explicita el tipo de objeto referenciado en una declarar visibilidad “protegida” en variables de
variable. instancia y métodos.
Persona a = new Profesor();
Profesor b = a; // ERROR  Los miembros de una clase con visibilidad
Persona Persona a = new Profesor(); protegida son sólo accesibles desde la misma clase
Profesor b = (Profesor) a;
Alumno c = (Alumno) a;
// OK
// ERROR
o desde cualquier subclase de ella (no son
accesibles desde otras clases).
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

Franco Guidi Polanco 69 Franco Guidi Polanco 70

Miembros protegidos de una clase Miembros protegidos de una clase

 Por lo tanto, una subclase hereda de su  Ejemplo:


superclase: public class Persona { public class Alumno extends
Persona {
  Variables de instancia protegidas y públicas protected String rut;
protected String nombre; private String rolUCV;
  Métodos protegidos y públicos
public Persona(String r, String n) { public Alumno() {
rut = r; super( 000000-0 , N/A );
nombre = n; rolUCV = 000000-0";
} }
public void setRut(String r){
rut = r; } public String quiénSoy(){
public String getRut(){ return rut + nombre
return rut; } + rolUCV;
public void setNombre(String n){ }
nombre = n; } }
public String getNombre(){
return nombre; }

Franco Guidi Polanco 71 Franco Guidi Polanco 72


Identificación de superclases
  Contexto: se está desarrollando
una aplicación que trabaja con
CD’s, DVD’s y discos de vinilo.

  Problema: se establece que a


pesar de tener sus propios
POO en Java IV: Herencia atributos, todos ellos disponen de
código, sello discográfico y autor. ProductoMusical
(Parte 6) Se desea evitar duplicidad de
código.
código
sello
autor
Franco Guidi Polanco   Decisión: se determina la
conveniencia de crear la clase
Escuela de Ingeniería Industrial “ProductoMusical”, que agrupa las
Pontificia Universidad Católica de Valparaíso, Chile propiedades comunes de los tres
tipos de productos. CD DVD Vinilo
fguidi@ucv.cl

La superclase aparece por factorización


de propiedades comunes
Actualización: 22 de Agosto de 2011
Franco Guidi Polanco 74

Clases abstractas Clases abstractas

  En el ejemplo anterior la clase ProductoMusical es abstracta (no  Otro ejemplo: un software trabaja con distintas
representa entidades presentes en el dominio).
figuras geométricas, todas ellas polígonos, con
  Esta condición se explicita en el diseño, declarando la clase como
abstracta. algunas propiedades en común (ej. cantidad de
lados).
public abstract class ProductoMusical {
ProductoMusical
{abstract} private int código;

código
private String sello;
Polígono
sello ...
autor
}

CD DVD Vinilo

  Una clase abstracta no puede ser instanciada, ha sido diseñada sólo


para ser extendida.

Franco Guidi Polanco 75 Franco Guidi Polanco 76


Clases abstractas Métodos abstractos

public abstract class Poligono {  Supongamos que en el ejemplo


protected int lados; anterior todos los polígonos deben
public void setLados(int l){ proveer un método de cálculo de área.
Polígono lados = l; Polígono
}  Conflicto de “fuerzas” en diseño:
...   Todos los polígonos deben proveer el
} método, por lo tanto debiese “aparecer” a
nivel de la superclase Polígono.
  La operación del método depende de cada
polígono concreto (ej. área de cuagrado:
public class Cuadrado extends Poligono { lado2, área de triángulo base * altura /2,
private int longitud; etc.), por lo tanto no puede establecerse
public void setLongitud(double l) { una lógica común a nivel de superclase.
longitud = l;
}  Solución: declarar método como
... abstracto en la superclase.
}

Franco Guidi Polanco 77 Franco Guidi Polanco 78

Métodos abstractos Métodos abstractos


public abstract class Poligono {
 Un método abstracto es un método que se declara protected int lados;
en una superclase, pero sin proveer public int setLados(int l){
lados = l;
implementación. }
public abstract double getArea();
 La implementación de un método abstracto se Polígono ...
difiere para sus subclases. }

 Una clase que declara uno o más métodos


public class Cuadrado extends Poligono {
abstractos es necesariamente abstracta (y debe private double longitud;
ser declarada como tal). public void setLongitud(double l) {
longitud = l;
 Si una subclase no provee implementación para un }
public double getArea(){
método abstracto que hereda de su superclase, es return longitud*longitud;
necesariamente abstracta (y debe ser declarada }
...
como tal). } 80

Franco Guidi Polanco 79 Franco Guidi Polanco 80


Consecuencias del uso de métodos abstractos

 Si una superclase declara algún método


abstracto, entonces:
  Las subclases concretas deben implementarlo.
  Las variables de referencia declaradas del tipo
de la superclase pueden recibir invocaciones al
método abstracto, sin necesidad de casting.
Ejemplo:
Polígono figura = new Triángulo(); getArea() fue
declarado como
método abstracto
double sup = figura.getArea(); en Polígono.

Franco Guidi Polanco 81

También podría gustarte