Vous êtes sur la page 1sur 11

Herencia y polimorfismo

Índice
Herencia ... 2
Herencia: una subclase Alumno ... 6
Curso de Java Subclase Alumno2 con atributo de clase Persona ... 12
Los modificadores protected y final ... 14
Jerarquía de clases ... 15
Clases abstractas ... 18
Compatibilidad entre objetos de distintas clases ... 25
Polimorfismo y vinculación dinámica ... 27
Herencia y polimorfismo Moldes de objetos y el operador instanceof ... 28
Interfaces ... 29
La interfaz Cloneable ... 31
Clases internas 35

El lenguaje Java — Tema 6 — Herencia y polimorfismo


Curso de Java Tema 5 – Herencia y polimorfismo - 1

Herencia Herencia

Mecanismo exclusivo y fundamental de la POO. Base de la aplicación del mecanismo de herencia:


La herencia no está contemplada en la programación „ Suficientes similitudes:
basada en tipos (TAD). Todas las características de la clase existente
Es el principal mecanismo que ayuda a fomentar y (o la gran mayoría de ellas)
facilitar la reutilización del software: resultan adecuadas para la nueva.
Las clases como componentes software reutilizables. „ En la nueva clase se ampliará y/o redefinirá
Si se necesita una nueva clase de objetos y se detectan suficientes el conjunto de características.
similitudes con otra clase ya desarrollada, se toma esa clase Características de las clases que se adoptan:
existente como punto de partida para desarrollar la nueva: Todos los miembros definidos en las clases.
9 Se adoptan automáticamente características ya implementadas „ Atributos
⇒ Ahorro de tiempo y esfuerzo „ Métodos
9 Se adoptan automáticamente características ya probadas Dependiendo de la forma en que se aplique el mecanismo de
⇒ Menor tiempo de prueba y depuración herencia, en la nueva clase se puede tener o no acceso a ciertas
características heredadas (a pesar de que se adopten todas).

Curso de Java Tema 5 – Herencia y polimorfismo - 2 Curso de Java Tema 5 – Herencia y polimorfismo - 3
Herencia Herencia

La relación de herencia se establece entre una nueva clase La relación de herencia se establece entre una clase Nueva
(referida aquí con el nombre Nueva) y una clase ya existente y una clase Existente.
(referida aquí con el nombre Existente).
Sobre la clase que hereda de la existente:
Un poco de terminología: 9 Nueva hereda todas las características de Existente.
9 Existente se dice que es la clase base, la clase madre 9 Nueva puede definir características adicionales.
o la superclase (término genérico de la POO). 9 Nueva puede redefinir características heredadas de Existente.
9 Nueva se dice que es la clase derivada, la clase hija 9 El proceso de herencia no afecta de ninguna forma a la superclase
o la subclase (término genérico de la POO). Existente.
9 También se utiliza el término derivación para Para que una nueva clase sea subclase
referirse a la herencia. de otra existente basta con añadir Existente
9 La clase Nueva es la que tiene establecida la relación de extends existente
herencia con la clase Existente; Existente no necesita a a continuación del nombre de la nueva:
Nueva, pero Nueva sí necesita la presencia de Existente. public class Nueva extends Existente { Nueva
...

Curso de Java Tema 5 – Herencia y polimorfismo - 4 Curso de Java Tema 5 – Herencia y polimorfismo - 5

Herencia: una subclase Alumno Herencia: una subclase Alumno

Recordemos la clase Persona del tema anterior. public class Alumno extends Persona {
...
Vamos a crear una subclase Alumno para representar alumnos
}
de una clase.
Por el mero hecho de indicar que Alumno es subclase de Persona,
9 Los alumnos también tienen NIF, nombre, apellidos y edad:
Los atributos de la clase Persona son adecuados para Alumno. los objetos de la clase Alumno ya tienen automáticamente 4
atributos y 12 métodos, los heredados de la clase Persona.
9 Los métodos de la clase Persona, en principio, parecen todos
ellos adecuados para la clase Alumno. En la subclase Alumno obviamente se puede acceder a lo público
de la superclase Persona, pero NO se puede acceder a lo privado
Los alumnos son personas de la superclase Persona (los atributos en este caso).
Ahora nos centramos en lo que hay que añadir en la subclase:
Resulta adecuado aplicar el mecanismo de herencia y crear
la nueva clase (Alumno) a partir de la existente (Persona). 9 Un atributo curso.
public class Alumno extends Persona { 9 Accedente y mutador para el nuevo atributo.
...
}

Curso de Java Tema 5 – Herencia y polimorfismo - 6 Curso de Java Tema 5 – Herencia y polimorfismo - 7
Herencia: una subclase Alumno Herencia: una subclase Alumno

public class Alumno extends Persona { public class Alumno extends Persona {
private int curso; private int curso;

// Accedente // Constructor predeterminado


public int dameCurso() { return curso; } public Alumno() {
super();
// Mutador curso = 1;
public void ponCurso(int curso) { this.curso = curso; }
}
// Constructor parametrizado
}
public Alumno(long dni, int edad, String nombre,
La clase Alumno ya tiene un atributo y 2 métodos más (propios). String apellidos, int curso) {
super(dni, edad, nombre, apellidos);
this.curso = curso;
En la subclase Alumno nos faltan los constructores. }
En los constructores podemos aprovechar lo que ya hacen public int dameCurso() { return curso; }
los constructores de la superclase Persona, public void ponCurso(int curso) { this.curso=curso; }
invocándolos por medio de la palabra reservada super. }

Curso de Java Tema 5 – Herencia y polimorfismo - 8 Curso de Java Tema 5 – Herencia y polimorfismo - 9

Herencia: una subclase Alumno Herencia: una subclase Alumno

Redefinición de métodos public class Alumno extends Persona {


private int curso;
Algunos de los métodos heredados pueden no resultar adecuados public Alumno() {
super();
(en mucho o en poco). Resulta necesario volver a desarrollarlos curso = 1;
en la subclase. Para hacerlo basta crear un método en la subclase }
public Alumno(long dni, int edad, String nombre,
con el mismo nombre que el de la superclase y entonces se pasará String apellidos, int curso) {
por alto éste y se ejecutará el de la subclase. super(dni, edad, nombre, apellidos);
this.curso = curso;
Pero si en un método redefinido se quiere ejecutar un método de la }
superclase que se ha redefinido, se puede utilizar la palabra clave public int dameCurso() { return curso; }
public void ponCurso(int curso) { this.curso = curso; }
super para pasarle el correspondiente mensaje. public String toString() {
public String toString() { // De la subclase Alumno return super.toString() + "Curso: " + curso + "\n";
}
return super.toString() + "Curso: " + curso + "\n"; public void leer() {
} super.leer();
System.out.print("Curso: ");
curso = MyInput.readInt();
}
} Alumno.java

Curso de Java Tema 5 – Herencia y polimorfismo - 10 Curso de Java Tema 5 – Herencia y polimorfismo - 11
Subclase Alumno2 con atributo de clase Persona Subclase Alumno2 con atributo de clase Persona

public class Alumno2 extends Persona { public int dameCurso() { return curso; }
private int curso; 1
private Persona profesor; Persona public Persona dameProfesor() { return profesor; }
public Alumno2() { public void ponCurso(int curso) { this.curso = curso; }
super();
public void ponProfesor(Persona profesor)
curso = 1; Alumno2
{ this.profesor = profesor; }
profesor = null;
} public String toString() {
public Alumno2(long dni, int edad, String nombre, String cadena = super.toString() + "Curso: " + curso
String apellidos, int curso, Persona profesor) { + "\nProfesor: ";
super(dni, edad, nombre, apellidos); if(profesor == null) cadena += "no asignado.\n";
this.curso = curso; else cadena += profesor.nombreCompleto() + "\n";
this.profesor = profesor; return cadena;
} }
public Alumno2(long dni, int edad, String nombre, public void leer() {
String apellidos, int curso) { super.leer();
super(dni, edad, nombre, apellidos); System.out.print("Curso: ");
this.curso = curso; curso = MyInput.readInt();
this.profesor = null; }
} . . . } Alumno2.java

Curso de Java Tema 5 – Herencia y polimorfismo - 12 Curso de Java Tema 5 – Herencia y polimorfismo - 13

Los modificadores protected y final Jerarquía de clases

Si se quiere permitir que en las subclases se pueda acceder A medida que se establecen relaciones de herencia entre las clases,
a los atributos de la superclase (o a métodos privados) implícitamente se va construyendo una jerarquía de clases.
se declararán éstos como protected en lugar de private.
En forma de árbol:
public class Persona { Object
protected Nif nif;
protected int edad;
protected String nombre, apellidos; Persona
...

Alumno Administrativo Profesor


Y si se quiere evitar que se creen subclases de una clase se debe
declarar como final.
public final class Persona { Oficial Libre Tiempo- Tiempo-
... Completo Parcial

Catedratico Titular

Curso de Java Tema 5 – Herencia y polimorfismo - 14 Curso de Java Tema 5 – Herencia y polimorfismo - 15
Jerarquía de clases Jerarquía de clases

Utilizando diagramas de UML (omitiendo la clase Object): Cuanto más arriba en la jerarquía,
más abstractas son las clases Persona

(menor nivel de detalle). Alumno Administrativo Profesor


Persona
A medida que se desciende
por la jerarquía aumenta Oficial Libre Tiempo- Tiempo-
el nivel de detalle Completo Parcial

Alumno Administrativo Profesor (disminuye la abstracción).


Catedratico Titular
Así, una Persona es una entidad
mucho más abstracta y general que un Titular.
Oficial Libre TiempoCompleto TiempoParcial „ Cada clase de la jerarquía debe implementar todas las
características que son comunes a todas sus subclases.
„ Cada subclase debe contemplar únicamente las peculiaridades
Catedratico Titular que la distinguen de su superclase.

Curso de Java Tema 5 – Herencia y polimorfismo - 16 Curso de Java Tema 5 – Herencia y polimorfismo - 17

Clases abstractas Clases abstractas

En ocasiones tendremos definidas clases en la jerarquía que ObjetoGrafico Clases abstractas


simplemente recogen las características comunes de otra serie de
clases (sus descendientes), pero que no se van a (o no se deben)
utilizar para crear ejemplares. Circulo Punto Paralelogramo
Clase abstracta:
9 Modela el comportamiento común de sus clases derivadas.
Elipse Cuadrado Rombo
9 Implementa métodos que son comunes a todas sus subclases.
9 Establece métodos que necesariamente han de ser
ObjetoGrafico y
implementados por sus subclases (las clases derivadas).
Paralelogramo son Rectangulo Romboide
En el sistema no van a crearse ejemplares de la clase abstracta clases abstractas.
porque no serían objetos con existencia propia en el mundo real.
En el programa de dibujo sólo se van a crear objetos gráficos
Los objetos que se crearán serán ejemplares de las subclases concretos: puntos, elipses, círculos, cuadrados, rectángulos,
(aquellas que no sean también abstractas). rombos o romboides.
La clase abstracta puede definir atributos comunes a sus subclases.

Curso de Java Tema 5 – Herencia y polimorfismo - 18 Curso de Java Tema 5 – Herencia y polimorfismo - 19
Clases abstractas Clases abstractas

Para definir una clase como abstracta se coloca la palabra reservada // Clase Punto: no abstracta
abstract antes de class: public class Punto extends ObjetoGrafico {
private double x;
public abstract class ObjetoGrafico { private double y;
...
public Punto() {
Si en la clase abstracta se quiere obligar a que las subclases x = 0;
implementen un determinado método, basta declararlo como y = 0;
método abstracto. No tendrá cuerpo y terminará en punto y coma: }
public abstract class ObjetoGrafico { // Abstracta public Punto(double cx, double cy) {
public abstract String toString(); x = cx;
public abstract void leer(); y = cy;
public abstract boolean esCerrada(); }
}
public double dameX() { return x; }
Las subclases (no abstractas) no podrán compilarse si no public double dameY() { return y; }
implementan métodos con esos prototipos. public void ponX(double d) { x = d; }
ObjetoGrafico.java public void ponY(double d) { y = d; } . . .

Curso de Java Tema 5 – Herencia y polimorfismo - 20 Curso de Java Tema 5 – Herencia y polimorfismo - 21

Clases abstractas Clases abstractas

// Implementa todos los métodos abstractos: // Paralelogramo: otra clase abstracta

public void desplaza(double deltaX, double deltaY) { public abstract class Paralelogramo
x += deltaX; extends ObjetoGrafico {
y += deltaY; protected Punto esquina;
}
public Paralelogramo() { esquina = new Punto(0, 0); }
public String toString(){
return "(" + x + "," + y + ")"; public Punto dameEsquina() { return esquina; }
} public void ponEsquina(Punto p) { esquina = p; }

public boolean esCerrada() { return false; } // Implementa uno de los métodos abstractos
} public boolean esCerrada() { return true; }
// Todos los paralelogramos son cerrados.
}

Punto.java Paralelogramo.java

Curso de Java Tema 5 – Herencia y polimorfismo - 22 Curso de Java Tema 5 – Herencia y polimorfismo - 23
Clases abstractas Compatibilidad entre objetos de distintas clases

// Cuadrado: clase no abstracta Todos los alumnos son personas,


public class Cuadrado extends Paralelogramo {
protected double lado;
pero no todas las personas son alumnos
public Cuadrado() { A un identificador de la clase Persona (superclase)
super();
lado = 0;
se le puede asignar un objeto de la clase Alumno (subclase),
} pero a un identificador de la clase Alumno (subclase)
no se le puede asignar un objeto de la clase Persona (superclase)
public double dameLado() { return lado; }
public void ponLado(double d) { lado = d; }
// Implementa los otros dos métodos abstractos Persona unaPersona;
public String toString() { Alumno unAlumno;
return "[" + esquina.toString() + ", " + lado + "]"; ...
} unaPersona = unAlumno; // Correcto:
public void desplaza(double deltaX, double deltaY) { // todos los alumnos son personas
esquina.desplaza(deltaX, deltaY); unAlumno = unaPersona; // INCORRECTO:
}
// no todas las personas son alumnos
} Cuadrado.java

Curso de Java Tema 5 – Herencia y polimorfismo - 24 Curso de Java Tema 5 – Herencia y polimorfismo - 25

Compatibilidad entre objetos de distintas clases Polimorfismo y vinculación dinámica

Regla general de compatibilidad entre objetos: En la clase Lista está definido el método toString():
public String toString() {
String cad = "Elementos de la lista:\n\n";
A un identificador de una clase sólo se le pueden asignar for(int i = 0; i < _cont; i++)
objetos de esa clase o de cualquiera de sus subclases cad += _array[i].toString() + "\n";
return cad;
Esta compatibilidad resulta muy útil cuando se quieren manejar }
listas de objetos: basta declarar un array de objetos de la Si en la lista se guardan tanto Personas como Alumnos,
superclase y podremos asignar a las distintas posiciones del array no podemos saber si cada _array[i] hace referencia
objetos de esa clase y de cualquiera de las subclases. a una Persona o a un Alumno. Y consecuentemente,
La lista de Personas puede perfectamente guardar Alumnos. no podemos saber si se ejecutará el método toString()
No hay que cambiar nada. Todo funciona sin cambios. de la clase Persona o el de la clase Alumno.
_array[i] puede tener distintas formas: es polimórfico.
La vinculación entre el mensaje y el método que corresponde
se realiza en tiempo de ejecución: vinculación dinámica.

Curso de Java Tema 5 – Herencia y polimorfismo - 26 Curso de Java Tema 5 – Herencia y polimorfismo - 27
Moldes de objetos y el operador instanceof Interfaces

Si queremos asignar a un identificador de una subclase Java no permite herencia múltiple (una clase extienda varias otras).
el objeto referenciado por un identificador de una de sus Sin embargo, por medio de los interfaces se puede conseguir un
superclases, deberemos utilizar un molde de objeto: efecto similar.
Persona unaPersona; Una interfaz es parecido a una clase abstracta, pero sólo puede
... tener definidos métodos abstractos y constantes (static/final).
Alumno unAlumno = (Persona) unaPersona; Ni atributos ni implementaciones de métodos.
Para que la asignación se pueda realizar, el objeto referenciado Se crear igual que las clases, pero utilizando interface
por unaPersona deberá ser en realidad un objeto Alumno. en lugar de class:
La regla de compatibilidad permite que unaPersona haga
public interface Comparable { // interfaz estándar
referencia a un objeto de clase Persona o a uno de clase Alumno. public int compareTo(Object obj); // sin abstract
Deberemos asegurarnos de que se trate de un objeto Alumno. }
El operador instanceof indica si el objeto apuntado por una Esta interfaz define un único método, que indica si el objeto
referencia es de una determinada clase: receptor es menor que el proporcionado (resultado negativo),
if(unaPersona instanceof Alumno) es mayor (resultado positivo) o es igual (0 como resultado).
unAlumno = (Persona) unaPersona; Recuérdese que Object es la clase raíz de la jerarquía.

Curso de Java Tema 5 – Herencia y polimorfismo - 28 Curso de Java Tema 5 – Herencia y polimorfismo - 29

Interfaces La interfaz Cloneable

Las clases pueden implementar interfaces, asegurando que incluyen Para que Java permita crear clones de los objetos de una clase
la funcionalidad descrita en la interfaz (o las interfaces). por medio del método clone() de la clase Object,
public class Persona2 implements Comparable { la clase debe implementar la interfaz Cloneable.
... public class Alumno3 extends Persona
public int compareTo(Object obj) { implements Cloneable {
String este = nombreCompleto().toUpperCase(); ...
String otro = }
((Persona) obj).nombreCompleto().toUpperCase();
return este.compareTo(otro);
Además, la clase debe redefinir el método clone() heredado
} Persona2.java de la clase Object. Y debe hacerlo de esta forma:
} public Object clone() { El método debe estar protegido con el
try { manejo de esa excepción frente a intentos
Nada impide que una clase herede de otra e implemente interfaces: return super.clone(); de clonación de objetos de superclases
public class Alumno extends Persona }
implements Comparable { catch (CloneNotSupportedException ex) {
... return null;
}
Y se pueden implementar varias interfaces (separadas por comas). } Alumno3.java

Curso de Java Tema 5 – Herencia y polimorfismo - 30 Curso de Java Tema 5 – Herencia y polimorfismo - 31
La interfaz Cloneable La interfaz Cloneable

public class PruebaAlumno3 { Para conseguir una copia profunda (deep copy), el método
public static void main(String args[]) {
clone() de la clase se debe encargar de obtener por su cuenta
Alumno3 al1 = new Alumno3(435762, 23, "Javier",
"Hernandez Perez", 4); los clones de los atributos que sean referencias.
Persona per = new Persona(112233, 22, "Pedro",
En la clase Persona se debe permitir la clonación:
"Gomez Alvarez");
al1.ponProfesor(per); public Object clone() {
System.out.println(al1); try {
Alumno3 al2 = (Alumno3) al1.clone(); return super.clone();
System.out.println(al2);
}
al1.ponNombre("Angel");
per = al1.dameProfesor();
catch (CloneNotSupportedException ex) {
per.ponNombre("Rosa"); Shallow copy (copia superficial) return null;
System.out.println(al1); El atributo profesor no se clona. }
System.out.println(al2); }
}
}

PruebaAlumno3.java Persona3.java

Curso de Java Tema 5 – Herencia y polimorfismo - 32 Curso de Java Tema 5 – Herencia y polimorfismo - 33

La interfaz Cloneable Clases internas

En la clase Alumno el método clone() debe crear el clon Una clase interna o anidada es una clase que está definida dentro
del profesor para colocarlo en su propio clon: de otra clase (como si fuera otro atributo):
public Object clone() { public class Clase {
Alumno4 al = (Alumno4) super.clone(); private int dato;
Persona3 per = (Persona3) profesor.clone(); public void metodo() {
al.ponProfesor(per); Interna ejemplar = new Interna();
return al; }
}
class Interna { Es una clase auxiliar
Como el método de la superclase Persona ya está protegido
public void otro() {
con el manejo de la excepción, aquí no hay que volver a protegerlo. dato++; // Puede acceder a los atributos
metodo(); // y a los métodos de la externa.
}
} Si la clase interna es anónima (sin nombre)
Alumno4.java } se crea automáticamente un ejemplar suyo.

PruebaAlumno4.java La clase interna sólo es conocida en aquella en la que se encuentra.

Curso de Java Tema 5 – Herencia y polimorfismo - 34 Curso de Java Tema 5 – Herencia y polimorfismo - 35
Paquetes: empaquetado de clases Paquetes: empaquetado de clases

Son agrupaciones de clases, interfaces y otros paquetes relacionados Para usar algún componente de un paquete hay que añadir una
entre sí, que favorecen la encapsulación. declaración de importación, que puede ser de un elemento o de
package nombrePaquete; todos los elementos.
Un solo elemento:
Todos los elementos contenidos en el archivo con la declaración
anterior formarán parte del paquete nombrePaquete. import Matricula.Alumno; Se importa sólo la clase Alumno
...
Podríamos crear un paquete con la información relativa a la Alumno alumno1;
matriculación de alumnos, que incluyera alumnos, asignaturas, ...
notas, profesorado, horarios, etcétera.
Todo el paquete sin cualificación:
Posteriormente se podrían usar para diferentes aplicaciones de import Matricula.*;
matriculación: institutos, colegios, ... Se importa todo y para usar los
... elementos no es necesario
package Matricula; Alumno alumno1; cualificarlos
class Alumno { . . } ...
class Asignatura { . . . }
...

Curso de Java Tema 5 – Herencia y polimorfismo - 36 Curso de Java Tema 5 – Herencia y polimorfismo - 37

Paquetes: ejemplo de empaquetamiento Paquetes: ejemplo

Creo el directorio que va a contener clases (relacionadas): Si quiero usar dichas clases en cualquier otro programa:
cursojava
Æ utils import cursojava.utils.teclado.*;
Carpeta/package con utilidades Puedo usar todas las clases
Æ teclado
de lectura por teclado class PruebaPaq {
públicas del package teclado

Y en ese directorio creo dos archivos, cada uno con una clase útil: public static void main(String[] args){
Clase01 c = new Clase02();
package cursojava.utils.teclado; Clase02 d = new Clase02()}
public class Clase01 {} A rchivo Clase01.java }

package cursojava.utils.teclado; 9 Cuando el compilador se encuentra import, comienza a buscar


public class Clase02 {} A rchivo Clase02.java en los subdirectorio de CLASSPATH, y encuentra \utils\teclado,
porque CLASSPATH= C:\....
Al compilar dichos programa, se empaquetan dos clases .class en
9 Ahora puedo utilizar las clases públicas Clase01 y Clase02.
el directorio teclado.

Curso de Java Tema 5 – Herencia y polimorfismo - 38 Curso de Java Tema 5 – Herencia y polimorfismo - 39
Paquetes Paquetes

Todas las clases se organizan en paquetes incluso las clases del


sistema. Para utilizar algunas clases de un paquete o paquetes
enteros se utiliza la instrucción import.
Al importar un paquete sólo son accesibles sus elementos declarados
como públicos, salvo para las clases que heredan de alguna de las
declaradas en el paquete.
Ejemplos de paquetes incluidos en el sistema:
java.lang: Clases esenciales de java: Object, String...
java.util: Utilidades y estructuras de datos
java.io: Todo lo relacionado con entrada/Salida
java.net: Soporte para programación en red
java.awt, java.swing: Soporte para interfaces gráficas

Curso de Java Tema 5 – Herencia y polimorfismo - 40 Curso de Java Tema 5 – Herencia y polimorfismo - 41

El modificador protected Ejercicio

9 Crear 5 clases vacías (Clase1, Clase2, Clase3, Clase 4 y Clase5)


package p1 package p2 y empaquetarlas en C:/Prueba/Izar.

class C1 class C2 extends C1 9 Crear un programa PruebaPaquete en el proyecto Tema 6 que importe
alguna clase para probarla
protected intx x se puede leero
m odificaren C2

¡Ojo!: JCreator crea las


carpetas de los paquetes
debajo de la carpeta del
class C3 class C4 proyecto actual, por lo que
habrá que cambiar el
C1 c1; C1 c1; ClassPath para que encuentre
c1.x se puede leero c1.x no se puede leer dicho paquete
m odificar o m odificar

Curso de Java Tema 5 – Herencia y polimorfismo - 42 Curso de Java Tema 5 – Herencia y polimorfismo - 43

Vous aimerez peut-être aussi