El documento describe los conceptos de herencia y polimorfismo en programación orientada a objetos. La herencia permite que una clase herede los campos y métodos de otra clase, creando jerarquías de clases. El polimorfismo permite que métodos con el mismo nombre tengan comportamientos diferentes dependiendo de la clase que los invoca.
2. Herencia
Mecanismo para extender las propiedades y comportamientos (campos y
métodos) de otras clases
Creación de nuevas clases a partir de otras ya existentes
Clase heredera = clase extendida o derivada
Herencia simple
Composición: utlizar objetos dentro de otros objetos
Herencia ≠ Composición
menor detalle
jerarquía
de clases
mayor detalle
3. Herencia
Superclase (Java) o Clase base (C++)
Subclase (Java) o Clase derivada (C++)
Java
Superclase (superclase directa)
Subclase (subclase directa)
Superclase indirecta
Subclase indirecta
Herencia simple: Una clase se deriva “sólo” de una superclase (Java).
Herencia múltiple: Una clase se deriva de “más de una” superclase directa
(C++).
4. Herencia
Superclase (Java) o Clase base (C++)
Subclase (Java) o Clase derivada (C++)
Java
Superclase (superclase directa)
Subclase (subclase directa)
Superclase indirecta
Subclase indirecta
Herencia simple: Una clase se deriva “sólo” de una superclase (Java).
Herencia múltiple: Una clase se deriva de “más de una” superclase directa
(C++).
5. clase Padre
campo primero;
campo segundo;
campo tercero;
método haceAlgoUno(){...}
método haceAlgoDos(){...}
método haceAlgoTres(){...}
clase SegundoHijo
campo primero;
clase PrimerHijo campo segundo;
campo primero; campo tercero;
campo segundo; campo adicionalSegundoHijoUno;
campo tercero; campo adicionalSegundoHijoDos;
campo adicionalPrimerHijoUno;
campo adicionalPrimerHijoDos; método haceAlgoUno(){...}
método haceAlgoDos(){...}
método haceAlgoUno(){...} método haceAlgoTres(){...}
método haceAlgoDos(){...} método inicializacionSegundoHijo(){...}
método haceAlgoTres(){...} método impresionSegundoHijo(){...}
método asignacionPrimerHijo(){...} método calculoSegundoHijo(){...}
método destruccionPrimerHijo(){...} método toStringSegundoHijo(){...}
6. clase SegundoHijo
campo primero;
campo segundo;
campo tercero;
campo adicionalSegundoHijoUno;
campo adicionalSegundoHijoDos;
método haceAlgoUno(){...} clase ExtensionSegundoHijo
método haceAlgoDos(){...} campo primero;
método haceAlgoTres(){...} campo segundo;
método inicializacionSegundoHijo(){...} campo tercero;
método impresionSegundoHijo(){...} campo adicionalSegundoHijoUno;
método calculoSegundoHijo(){...} campo adicionalSegundoHijoDos;
método toStringSegundoHijo(){...}
método haceAlgoUno(){...}
método haceAlgoDos(){...}
método haceAlgoTres(){...}
método inicializacionSegundoHijo(){...}
método impresionSegundoHijo(){...}
método calculoSegundoHijo(){...}
método toStringSegundoHijo{...}
método completarSegundoHijo(){...}
método obtenerSegundoHijo(){...}
método dividirSegundoHijo(){...}
7. public class Empleado {
String nombre;
int sueldo;
public Empleado(String nombre, int sueldo) {
this.nombre = nombre; casting
this.sueldo = sueldo;
}
public void aumentarSueldo(int porcentaje) {
sueldo += (int)(sueldo * porcentaje / 100);
}
public String toString() {
return "Nombre: " + nombre + " Sueldo: " + sueldo;
}
}
****************************************
public class Ejecutivo extends Empleado {
int presupuesto;
public Ejecutivo(String nombre, int sueldo) {
super(nombre, sueldo);
}
void asignarPresupuesto(int p) {
presupuesto = p;
}
}
9. Redefinición de métodos
•
mismos nombres pero con diferente comportamiento
class Object {
... ... ...
public String toString(){ ... }
... ... ...
}
class Empleado {
... ... ...
public String toString(){
return "Nombre: " + nombre + " Sueldo: " + sueldo;
}
}
class Ejecutivo extends Empleado {
... ... ...
public String toString(){
String s = super.toString();
s = s + " Presupuesto: " + presupuesto;
return s;
}
}
10. Inicialización de clases derivadas
•
método constructor
•
referencia super
class Ejecutivo extends Empleado {
int presupuesto;
Ejecutivo (String n, int s) {
super(n,s);
... ... ...
}
}
***************************
public String toString(){
String s = super.toString();
s = s + " Presupuesto: " + presupuesto;
return s;
}
11. Modificadores de acceso
➢public: Todo el mundo puede acceder al elemento. Si es un
atributo, todo el mundo puede ver el elemento, es decir, usarlo y
asignarlo. Si es un método todo el mundo puede invocarlo.
➢private: Sólo se puede acceder al elemento desde métodos de la
clase, o sólo puede invocarse el método desde otro método de la
clase.
➢protected: Sus métodos/atributos tienen acceso a nivel de clase,
paquete y subclase.
➢sin modificador: Se pueden acceder/invocar sus elementos
desde cualquier clase del paquete donde se define la clase.
12. Modificador protected
combinación de public y private
acceso a clases derivadas y del mismo package
class Empleado {
protected int sueldo;
. . .
}
Clase Padre
datos y métodos protected
datos y métodos private
Clase Hija
datos y métodos cualesquiera
Accesibilidad de datos y métodos protected se
encuentren o no dentro del mismo package
13. Clase Cualquiera
Clase Padre
datos y métodos cualesquiera
datos y métodos protected
datos y métodos private
Clase Hija
packageEjemploDeProtected datos y métodos de clase hija
Clase Padre
datos y métodos protected
datos y métodos private
Clase Hija
datos y métodos cualesquiera
packageEjemploDeProtected packageEjercicios
14. Resumen de modificadores
Modificador Clase Package Subclase Otros
public Y Y Y Y
protected Y Y Y N
sin modficador Y Y N N
private Y N N N
15. packageUno packageDos
subclase
claseA subclaseA
claseB claseC
Visibilidad de claseA
Modificador ClaseA ClaseB SubclaseA claseC
public Y Y Y Y
protected Y Y Y N
sin modficador Y Y N N
private Y N N N
16. packageUno packageDos packageTres
claseA claseB claseW claseY subClaseZ
(hereda de
claseC claseD claseX claseZ claseZ)
considerar el acceso a campos y métodos (miembros)
claseA y claseW tienen miembros públicos
claseB, claseY y subClaseZ tienen miembros protected
claseC y claseX tienen miembros sin modificador
claseD y claseZ tienen miembros private
1- claseC puede acceder a claseD ? ... y viceversa ?
2- claseX puede acceder a claseC ? ... y claseZ ?
3- claseB puede acceder a claseD ? ... y viceversa ?
4- claseA puede acceder a claseZ ? ... y viceversa ?
5- claseY puede acceder a claseZ ? ... y viceversa ?
6- claseZ puede acceder a claseD ? ... y viceversa ?
7- claseW puede acceder a claseD ? ... y viceversa ?
8- claseW puede acceder a claseA ? ... y viceversa ?
9- clase subClaseZ puede acceder a claseC ? ... y a claseB ?
10- clase subClaseZ puede acceder a claseD ? ... y a claseW ?
17. packageUno packageDos packageTres
claseA claseB claseW claseY subClaseZ
(hereda de
claseC claseD claseX claseZ claseZ)
considerar el acceso a campos y métodos (miembros)
claseA y claseW tienen miembros públicos
claseB, claseY y subClaseZ tienen miembros protected
claseC y claseX tienen miembros sin modificador
claseD y claseZ tienen miembros private
1- claseC puede acceder a claseD ? ... y viceversa ? NO SI
2- claseX puede acceder a claseC ? ... y claseZ ? NO NO
3- claseB puede acceder a claseD ? ... y viceversa ? NO SI
4- claseA puede acceder a claseZ ? ... y viceversa ? NO SI
5- claseY puede acceder a claseZ ? ... y viceversa ? NO SI
6- claseZ puede acceder a claseD ? ... y viceversa ? NO NO
7- claseW puede acceder a claseD ? ... y viceversa ? NO SI
8- claseW puede acceder a claseA ? ... y viceversa ? SI SI
9- clase subClaseZ puede acceder a claseC ? ... y a claseB ? NO NO
10- clase subClaseZ puede acceder a claseD ? ... y a claseW ? NO SI
18. Upcasting y downcasting (RTTI = Run-Time Type Identification)
up-casting = “subir a la clase padre”
down-casting = “bajar a la clase hijo”
Considerar las clases Automovil y AutomovilCarrera. Suponiendo que
acelerar() esté en Automovil y se haya especializado en AutomovilCarrera.
Up-casting
AutomovilCarrera formulaUno = new AutomovilCarrera();
String stringAcelera = formulaUno.acelerar(); //para competir
String stringAcelera2 = ((Automovil) formulaUno).acelerar(); //para ciudad
*******************************************
Automovil[] arrayAutos = { new Automovil(), new AutomovilCarrera() };
boolean valorQuitarVolante = arrayAutos[0].quitarVolante(); // ERROR
boolean valorQuitarVolante2 = ((AutomovilCarrera)
arrayAutos[1]).quitarVolante(); Down-casting
up-casting
down-casting
19. Operador cast
Conversión de referencias
Empleado emp = new Ejecutivo("Jefe principal" , 2000);
Ejecutivo ej = (Ejecutivo)emp; // se convierte la referencia de tipo
ej.asignarPresupuesto(1500); // correcto
ej.asignarSueldo(500); // correcto
Empleado emp = new Empleado("Ricardo Castillo" , 2000);
Ejecutivo ej = (Ejecutivo)emp; // incorrecto
20. Ejemplo (Punto/Circulo/Cilindro):
public class Punto { Superclase de Circulo
private int x;
private int y;
Invocación del constructor (de la misma
public Punto( ){
this( 0, 0 ); clase Punto) que recibe 2 parámetros de
} tipo int.
public Punto(int x, int y){ Constructores
this.x = x; sobrecargados
this.y = y;
}
(Punto)
public int getX( ){ “this.x” hace referencia al atributo “x” de
return x; la clase.
}
public void setX(int x){
this.x = x;
}
public int getY( ){
return y;
}
public void setY(int y){
this.y = y;
}
}
21. Ejemplo (Punto/Circulo/Cilindro):
public class Circulo extends Punto { Subclase de Punto y Superclase de Cilindro
private double radio;
public Circulo( ){ Invocación del constructor (de la misma
this( 0.0 ); clase Circulo) que recibe 2 parámetros
}
de tipo int y un double.
public Circulo(double radio){
this( 0, 0, radio );
} Constructores
public Circulo(int x, int y, double radio){
sobrecargados
super( x, y ); (Circulo)
this.radio = radio;
}
Invocación del constructor (de la “super”
public double getRadio( ){ clase Punto) que recibe 2 parámetros de
return radio;
} tipo int.
public void setRadio(double radio){
this.radio = radio;
}
public double getDiametro( ){
return radio * 2.0;
}
public double getArea( ){
return Math.PI * radio * radio;
}
public double getCircunferencia( ){
return Math.PI * getDiametro( );
}
}
22. Ejemplo (Punto/Circulo/Cilindro):
public class Cilindro extends Circulo { Subclase de Circulo
private double altura;
public Cilindro( ){
this( 0, 0, 0.0, 0.0 ); Invocación de distintos constructores de
}
la misma clase Cilindro.
public Cilindro(double altura){
this( 0, 0, 0.0, altura );
} Constructores
public Cilindro(double radio, double altura){ sobrecargados
this( 0, 0, radio, altura ); (Cilindro)
}
public Cilindro(int x, int y, double radio, double altura){ Invocación del constructor (de la “super”
super( x, y, radio );
this.altura = altura;
clase Circulo) que recibe 2 parámetros
} de tipo int y un double.
public double getAltura( ){
return altura;
} Redefinición del método “getArea( )”
public void setAltura(double altura){
heredado de la “super” clase Circulo
this.altura = altura;
}
public double getArea( ){
return 2 * super.getArea( ) + super.getCircunferencia( ) * altura;
}
public double getVolumen( ){
return super.getArea( ) * altura;
Invocación del método “getArea( )” de la
} “super” clase Circulo
}
23. Ejemplo (Punto/Circulo/Cilindro):
public class Principal {
public static void main(String args[]) {
Cilindro cil = new Cilindro( 5, 5, 4.0, 5.0 );
System.out.println( "Area = " + cil.getArea( )); Creación y manipulación de
System.out.println( "Altura = " + cil.getAltura( )); un objeto de tipo Cilindro.
System.out.println( "Volumen = " + cil.getVolumen( ));
}
}
24. Ejemplo 2 (Punto - static):
public class Punto {
private int x;
private int y;
static private int cont = 0; Atributo “static”
Punto( ){
x = 0;
y = 0;
++cont;
}
public void setX(int x){
this.x = x;
}
public int getX( ){
return this.x;
}
public void setY(int y){
this.y = y;
}
public int getY( ){
return this.y;
}
public int getCont( ){
return this.cont;
}
public void setCont(int cont){
this.cont = cont;
}
}
25. Ejemplo 2 (Punto - static):
public class Prueba {
static String mensaje = "Hola!";
El método main es un método “static”
public static void main(String[] args){
Punto p = new Punto( );
p.setX(5);
p.setY(4);
System.out.println( "X = " + p.getX( ) + ", Y = " + p.getY( ) + ", Cont = " + p.getCont( ) );
Punto p2 = new Punto( );
p2.setX(2);
p2.setY(8);
System.out.println( "X = " + p2.getX( ) + ", Y = " + p2.getY( ) + ", Cont = " + p2.getCont( ) );
p2.setCont(1000);
Punto p3 = new Punto( );
p3.setX(3);
p3.setY(9);
System.out.println( "X = " + p3.getX( ) + ", Y = " + p3.getY( ) + ", Cont = " + p3.getCont( ) );
}
}