Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Í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
Herencia Herencia
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
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;
Curso de Java Tema 5 – Herencia y polimorfismo - 8 Curso de Java Tema 5 – Herencia y polimorfismo - 9
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
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
...
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
Curso de Java Tema 5 – Herencia y polimorfismo - 16 Curso de Java Tema 5 – Herencia y polimorfismo - 17
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
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
Curso de Java Tema 5 – Herencia y polimorfismo - 24 Curso de Java Tema 5 – Herencia y polimorfismo - 25
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
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
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.
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
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 }
Curso de Java Tema 5 – Herencia y polimorfismo - 38 Curso de Java Tema 5 – Herencia y polimorfismo - 39
Paquetes Paquetes
Curso de Java Tema 5 – Herencia y polimorfismo - 40 Curso de Java Tema 5 – Herencia y polimorfismo - 41
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
Curso de Java Tema 5 – Herencia y polimorfismo - 42 Curso de Java Tema 5 – Herencia y polimorfismo - 43