Programación Orientada a Objetos en Java

Texto completo

(1)

Programación Orientada a

Objetos en Java

Sesión 9: Herencia

Motivación

Hasta ahora escribíamos clases para modelar objetos

mediante la agrupación de propiedades de tipos

básicos o complejos (otras clases)

Pero, ¿qué hacemos en los siguientes casos?

Queremos crear diferentes clases que comparten algo más

que el conjunto de métodos especificado por un interface

común

Queremos crear objetos que son un caso particular de los

definidos por una clase existente

Porque hacen más cosas

(2)

Clases que comparten algo más que un interface

• 

Vehículos

– 

Avión (Tiene

matricula

y vuela)

– 

Barco (Tiene

matrícula

y navega)

– 

Coche (Tiene

matrícula

y circula)

• 

Mamíferos

– 

Delfín (Tiene

pelo y mamas

, y nada)

– 

Mono (Tiene

pelo y mamas

, y trepa)

– 

Murciélago (

Tiene pelo y mamas

, y vuela)

• 

Figuras Cerradas

– 

Circulo (Tiene

coordenadas

, radio y se puede dibujar y mover)

– 

Estrella (Tiene

coordenadas

, número de brazos, y se puede dibujar y mover)

• 

Publicación

– 

Libro (Tiene

título, número de páginas

y autor)

– 

Cómic (Tiene

título, número de páginas

, guionista e Ilustrador)

– 

Periódico (Tiene

título, número de páginas

y fecha)

Clases que son ampliaciones de otras

Personaje (Tiene nombre y saluda)

– 

Guerrero (Personaje + lucha)

– 

Mago (Personaje + hechizar)

Pez (Tiene nombre y nada)

– 

Tiburón (Pez + ataca)

– 

Volador (Pez + vuela)

Esfera (tiene radio, volumen)

– 

Bola de Billar (Esfera + color, posición, velocidad)

– 

Planeta (Esfera + nombre, órbita)

(3)

Herencia

Técnica que permite crear clases a partir de otras para

ampliar o modificar la estructura y/o funcionalidad de las ya

existentes

Persona

Cadena

Fecha

Entero

Entero

Entero

Persona

Empleado

Entero

Agregación

de Miembros

(tiene)

Herencia (es un)

Clase padre o

clase base

Clase hija o

subclase

Atributos: x,y, radio

Método: mueve, pinta

Atributos: x,y, brazos

Método: mueve, pinta

Heredar para agrupar

Dos clases muy parecidas en cuanto a “qué” hacen y “cómo”

lo hacen son candidatas a heredar de una clase común donde

se define el “qué” y el “cómo” compartidos por ambas

Circulo

Estrella

Atributos: x,y

Métodos: mueve

Figura

Atributo: radio

Método: pinta

Atributo: brazos

Método: pinta

Circulo

Estrella

Ej: Tanto Circulo como Estrella

comparten los atributos de posición y

la posibilidad de ser desplazadas por

el plano, pero cada uno se define y se

pinta de una forma concreta y

específica

(4)

Heredar para ampliar

En muchas ocasiones necesitamos clases nuevas que tienen

en común algo con otra existente

Atributos: radio

Métodos: volumen

Esfera

Atributos: color, posicion,

velocidad

Método: mueve

Atributos: nombre,

órbita

Método: rota

BolaBillar

Planeta

Ej: Cada subclase recibe los atributos

y métodos del padre, pero cada una

los amplía de una forma particular

Creamos las subclases

Herencia en Java

Se usa la palabra

extends

Automáticamente se heredan todos los miembros y métodos

excepto los constructores

Se pueden tener múltiples hijos

Varias clases pueden heredar de la misma clase padre

Sólo se puede tener un padre

(5)

Ejemplo

V1.0

public class Circulo { private double x,y; private double radio; public Circulo(double x, double y, double radio) { this.x = x; this.y = y; this.radio = radio; }

// Métodos get y set public void dibuja() { ... } }

public class Estrella { private double x,y; private int brazos; public Estrella(double x, double y, int brazos) { this.x = x; this.y = y; this.brazos = brazos; }

// Métodos get y set

public void dibuja() { ... } }

public class Figura { private double x,y;

public Figura(double x, double y) { this.x = x;

this.y = y; }

public void setX(double d) { this.x = d; } public double getX() { return x; }

public void setY(double d) { this.y = d; } public double getY() { return y; } }

extends Figura { extends Figura {

¿Error?

Herencia

y Visibilidad

Los miembros y métodos privados de las clases ancestras no

son visibles para las subclases

Los públicos sí

Para hacer un miembro/método privado para cualquier clase

excepto para las que sean subclases se usa el modificador

(6)

Ejemplo

V2.0

public class Circulo extends Figura { private double radio;

public Circulo(double x, double y, double radio) { this.x = x; this.y = y; this.radio = radio; }

public void dibuja() { ... } }

public class Estrella extends Figura { private int brazos;

public Estrella(double x, double y, int brazos) { this.x = x; this.y = y; this.brazos = brazos; }

public void dibuja() { ... } }

public class Figura { protected double x,y;

public Figura(double x, double y) { this.x = x;

this.y = y; }

public void setX(double d) { this.x = d; } public double getX() { return x; } public void setY(double d) { this.y = d; } public double getY() { return y; } }

¿Siempre

posible?

Herencia y Constructores

Los constructores no se heredan

Los objetos de una subclase tienen sus miembros y los

heredados pero sólo puede acceder a los públicos y

protegidos

Al crear un objeto hay que inicializar todos los miembros, los

propios y los heredados, pero no todos los heredados son

públicos o protegidos por lo que no siempre podemos hacerlo

Es necesario poder invocar al constructor de la clase padre

para inicializar los miembros privados heredados

(7)

Uso de super

Invoca al constructor del padre (ancestro directo)

Se pueden pasar parámetros

Según los parámetros se invoca a un constructor u otro del

padre

Restricciones

Sólo una llamada

Sólo dentro de los constructores

Siempre en la primera línea del constructor

Ejemplo

V3.0

public class Circulo extends Figura { private double radio;

public Circulo(double x, double y, double radio) { super(x,y); this.radio = radio; }

public void dibuja() { ... }

public class Estrella extends Figura { private int brazos;

public Estrella(double x, double y, int brazos) { super(x,y); this.brazos = brazos; }

public class Figura { protected double x,y;

public Figura(double x, double y) { this.x = x; this.y = y;

}

public void setX(double d) { this.x = d; } public double getX() { return x; } public void setY(double d) { this.y = d; } public double getY() { return y; } }

(8)

Constructores implícitos

Reglas

Si no ponemos constructor las clases incluyen uno implícito sin

parámetros

Los constructores implícitos invocan automáticamente al constructor

implícito de su clase padre

Si en un constructor no se usa super, Java incluye automáticamente

un super() para invocar al constructor implícito de la clase padre

Consecuencias

Si la clase padre no tiene constructor implícito (o uno sin parámetros)

las clases derivadas deben tener algún constructor en el que se haga

un super válido, de lo contrario se produce error de compilación

Ejemplo

public class Hijo2 extends Padre { private double miembroHijo2; public Hijo2(double d) { this.miembroHijo2 = d; }

} public class Padre {

private double miembroPadre; public Padre(double d) { this.miembroPadre = d; }

}

public class Hijo1 extends Padre { public void metodo () { ... } }

(9)

Herencia y polimorfismo

Los objetos de clases descendientes son de hecho objetos de

su clase padre (y demás ancestros)

La herencia da lugar a una jerarquía de tipos de datos

class Test {

public static void main(String args[]) { Figura f = null;

Circulo sol = new Circulo(0,0, 2); Estrella polar = new Estrella(10,10, 5); sol.setX(10);

polar.setY(20); f = polar; f.setX(10);

if (f instanceof Estrella) { Estrella aux = (Estrella)f; int b = aux.getNumeroBrazos(); }

} }

La superclase Object

Java incluye una enorme biblioteca de clases organizadas de

forma jerárquica

La clase

Object

encabeza esta jerarquía

Object

es padre de todos las clases de forma directa o

indirecta, cualquier clase que no herede de ninguna será

descendiente directo de

Object

de forma automática

Por ser padre de todas siempre podemos usar variables de

tipo

Object

para almacenar referencias a otros objetos. Al

hacerlo perdemos el tipo aunque lo podremos recuperar

usando

instanceof

y un casting

(10)

Ejemplo de uso de Object

class Test {

public static void main(String args[]) { Object objeto = new Circulo(0,0, 5); Object logo[] = new Object[2]; logo[0] = new Circulo(0,0, 10); logo[1] = new Estrella(0,0, 3); if (objeto instanceof Circulo) { Circulo aux = (Circulo)objeto; System.out.println(aux.getRadio()); }

if (logo[1] instanceof Estrella) { Estrella aux = (Estrealla)logo[1];

System.out.println(aux.getBrazos()); } Figura f = (Figura)objeto; f.setX(f.getX()+5); f = (Figura)logo[1]; f.setY(f.getY()-5); } }

¿Cuándo utilizar herencia?

Si tengo varias clases parecidas entre si y no quiero repetir el

código en todas ellas, puedo hacer una clase que contenga la

parte común. Las clases específicas heredan de la común

tanto miembros como métodos.

Si quiero usar una clase pero necesito que haga más cosas y

no puedo modificarla porque no tengo su código fuente.

Podría hacer una clase que heredara de ella y ampliara su

funcionamiento.

Si quiero objetos parecidos a una clase pero más concretos.

Puedo hacer una clase que herede de esta pero modifique su

comportamiento (con sobrecarga que veremos en la siguiente

(11)

Ejercicio

1) Escribe una clase cuyos objetos representen un Conjunto

de cualquier tipo de objetos.

– 

Deben ser capaz de almacenar cualquier número de objetos de

cualquier tipo.

– 

Debe ser posible obtener la unión o la intersección de dos objetos de

tipo Conjunto.

Figure

Actualización...

Referencias

Actualización...