Sei sulla pagina 1di 33

Herencia en Java, con ejemplos

https://jarroba.com/herencia-en-la-programacion-orientada-a-objetos-ejemplo-en-java/

El proyecto de este post lo puedes descargar pulsando AQUI.


La Herencia es uno de los 4 pilares de la programacin orientada a objetos (POO) junto
con la Abstraccin, Encapsulacin y Polimorfismo. Al principio cuesta un poco entender estos
conceptos caractersticos del paradigma de la POO porque solemos venir de otro paradigma de
programacin como el paradigma de la programacin estructurada (ver la entrada"Paradigmas de
Programacin), pero se ha de decir que la complejidad est en entender este nuevo paradigma y
no en otra cosa. En esta entrada vamos a explicar de la mejor manera posible que es la herencia y
lo vamos a explicar con un ejemplo.
Respecto a la herencia se han dado muchas definiciones como por ejemplo la siguiente:
"La herencia es un mecanismo que permite la definicin de una clase a partir de la definicin de
otra ya existente. La herencia permite compartir automticamente mtodos y datos entre clases,
subclases y objetos.". As de primeras esta definicin es un poco difcil de digerir para aquellos que
estis empezando con la POO, as que vamos a intentar digerir esta definicin con un ejemplo en
el que veremos que la herencia no es ms que un "Copy-Paste Dinmico" o una forma de "sacar
factor comn" al cdigo que escribimos.
El ejemplo que proponemos es un caso en el que vamos a simular el comportamiento que
tendran los diferentes integrantes de la seleccin espaola de futbol; tanto los Futbolistas como
el cuerpo tcnico (Entrenadores, Masajistas, etc). Para simular este comportamiento vamos a
definir tres clases que van a representaran a objetos Futbolista, Entrenador y Masajista. De cada
unos de ellos vamos a necesitar algunos datos que reflejaremos en los atributos y una serie de
acciones que reflejaremos en sus mtodos. Estos atributos y mtodos los mostramos en el
siguiente diagrama de clases:

NOTA: en este diagrama y en adelante no vamos a poner los constructores y mtodos getter y
setter con el fin de que el diagrama nos quede grande e "intendible" aunque en un buen diagrama
de clases deberan aparecer para respetar el principio de encapsulacin de la POO

1
Como se puede observar, vemos que en las tres clases tenemos atributos y mtodos que
son iguales ya que los tres tienen los atributos id, Nombre, Apellidos y Edad; y los tres tienen los
mtodos de Viajar y Concentrarse:

A nivel de cdigo tenemos lo siguiente tras ver el diagrama de clases:

2
Lo que podemos ver en este punto es que estamos escribiendo mucho cdigo repetido ya
que las tres clases tienen mtodos y atributos comunes, de ahi y como veremos enseguida,
decimos que la herencia consiste en "sacar factor comn" para no escribir cdigo de ms, por
tanto lo que haremos sera crearnos una clase con el "cdigo que es comn a las tres clases" (a
esta clase se le denomina en la herencia como "Clase Padre o SuperClase") y el cdigo que
es especifico de cada clase, lo dejaremos en ella, siendo denominadas estas clases como "Clases
Hijas", las cuales heredan de la clase padre todos los atributos y mtodos pblicos o protegidos.
Es muy importante decir que las clases hijas no van a heredar nunca los atributos y mtodos
privados de la clase padre, as que mucho cuidado con esto. En resumen para que veis la ventaja
de la herencia, tenemos ahora una clase padre con 'n' lineas de cdigo y tres clases hijas con 'a', 'b'
y 'c' lineas de cdigos respectivamente, por tanto si hechis cuentas, hemos reducido nuestro
cdigo en '2n' lneas menos ya que antes tenamos '(n+a)+(n+b)+(n+c)' lneas de cdigo y ahora
tras aplicar herencia tenemos 'n+a+b+c' lneas, aunque tambin es cierto que tenemos una clase
ms, pero veremos un poco ms adelante la ventaja de tener esa clase padre. En resumen, al
"sacar factor comn" y aplicar herencia, tenemos las siguientes clases:

A nivel de cdigo, las clases quedaran implementadas de la siguiente forma:

3
Como podis observar ahora queda un cdigo mucho ms limpio, estructurado y con
menos lneas de cdigo, lo que lo hace ms legible, cosa que es muy importante y lo que todava
lo hace ms importante es que es un cdigo reutilizable, lo que significa que ahora si queremos
aadir ms clases a nuestra aplicacin como por ejemplo una clase Mdico, Utiller@, Jefe/a de
prensa etc. que pertenezcan tambin al equipo tcnico de la seleccin Espaola, lo podemos hacer
de forma muy sencilla ya que en la clase padre (SeleccionFutbol) tenemos implementado parte de
sus datos y de su comportamiento y solo habr que implementar los atributos y mtodos propios
de esa clase. Empezis a ver la utilidad de la herencia?.
Ahora si os habis fijado bien en el cdigo que se ha escrito y sino habis tenido
experiencia con la herencia en Java, habris podido observar dos palabras reservadas "nuevas"

4
como son "extends", "protected" y "super". Pues bien, ahora vamos a explicar el significado de
ellas:
extends: Esta palabra reservada, indica a la clase hija cual va a ser su clase padre, es decir
que por ejemplo en la clase Futbolista al poner "public class Futbolista extends
SeleccionFutbol" le estamos indicando a la clase 'Futbolista' que su clase padre es la clase
'SeleccionFutbol' o dicho de otra manera para que se entienda mejor, al poner esto
estamos haciendo un "copy-paste dinmico" diciendo a la clase 'Futbolista' que se 'copie'
todos los atributos y mtodos pblicos o protegidos de la clase 'SeleccionFutbol'. De aqu
viene esa 'definicin' que dimos de que la herencia en un 'copy-paste dinmico'.
protected: sirve para indicar un tipo de visibilidad de los atributos y mtodos de la clase
padre y significa que cuando un atributo es 'protected' o protegido, solo es visible ese
atributo o mtodo desde una de las clases hijas y no desde otra clase.
super: sirve para llamar al constructor de la clase padre. Quizs en el cdigo que hemos
puesto no se ha visto muy bien, pero a continuacin lo mostramos de formas ms clara,
viendo el constructor de los objetos pasndole los atributos:

Hasta aqu todo correcto, pero ahora vamos a ver como trabajamos con estas clases. Para
ver este funcionamiento de forma clara y sencilla vamos a trabajar con un objeto de cada clase y
vamos a ver como se crean y de qu forma ejecutan sus mtodos. Para ello empecemos
mostrando el siguiente fragmento de cdigo:

5
Lo primero que vemos es que nos creamos un objeto de cada clase, pasndole los
atributos al constructor como parmetro y despus "sorprendentemente" los metemos en un
"ArrayList" de objetos de la clase "SeleccionFutbol" que es la clase padre. Esto evidentemente te
lo permite hacer ya que todos los objetos son hijos de la misma clase padre. Luego como veis,
recorremos el ArrayList y ejecutamos sus mtodos "comunes" como son el 'Concentrarse' y el
'Viajar'. Este cdigo da como salida lo siguiente:

Todos los integrantes comienzan una concentracion. (Todos ejecutan el mismo mtodo)
Vicente Del Bosque -> Concentrarse
Andres Iniesta -> Concentrarse
Ral Martinez -> Concentrarse

Todos los integrantes viajan para jugar un partido. (Todos ejecutan el mismo mtodo)
Vicente Del Bosque -> Viajar
Andres Iniesta -> Viajar
Ral Martinez -> Viajar

Como veis al ejecutar todo el mismo mtodo de la clase padre el cdigo puesto funciona
correctamente.
Posteriormente vamos a ejecutar cdigo especfico de las clases hijas, de ah que ahora no
podamos recorrer el ArrayList y ejecutar el mismo mtodo para todos los objetos ya que ahora
esos objetos son nicos de las clases hijas. El cdigo es el siguiente:

6
Como vemos aunque el entrenador y los futbolistas asistan a un entrenamiento, los dos
hacen una funcin diferente en el mismo, por tanto hay que hacer mtodos diferentes para cada
una de las clases. Ya veremos cuando hablemos del polimorfismo que podremos ejecutar el mismo
mtodo para clases diferentes y que esos mtodos hagan cosas distintas. Como resultado al
cdigo mostrado tenemos lo siguiente:

Entrenamiento: Solamente el entrenador y el futbolista tiene metodos para entrenar:


Vicente Del Bosque -> Dirige un entrenamiento
Andres Iniesta -> Entrena

Masaje: Solo el masajista tiene el mtodo para dar un masaje:


Ral Martinez -> Da un masaje

Partido de Ftbol: Solamente el entrenador y el futbolista tiene metodos para el partido


de ftbol:
Vicente Del Bosque -> Dirige un partido
Andres Iniesta -> Juega un partido

CONCLUSIONES Y ACLARACIONES:
Esto ha sido todo lo que hemos contado sobre la herencia en esta entrada. El tema de la
herencia es un tema que puede ser un poco ms complejo de lo que lo hemos contado aqu, ya
que solo hemos contado lo que es la herencia simple (ya que Java por el momento es el nico tipo
de herencia que soporta) y no la herencia mltiple, que es un tipo de herencia en la que una clase
hija puede tener varios padres, aunque por el momento si estis empezando a aprender el
concepto de la herencia, con la herencia simple tenis ms que suficiente. Para los que os estis
iniciando en el mundo de la ingeniera informtica, habris podido ver que hemos puesto unos
ejemplo mostrando unos diagramas "un poco raros"; pues bien, estos diagramas se llaman
diagramas de clases (que los hemos realizado con la herramienta web de www.genmymodel.com)
y sirven para representar de forma grfica los atributos y mtodos de las clases y las relaciones
entre ellos, utilizando el lenguaje UML del cual intentaremos hablar ms adelante en otros
tutoriales. Por ltimo decir y aclarar que en esta entrada quizs no hemos utilizado una
terminologa correcta para explicar la herencia, pero lo hemos explicado de una forma algo
distinta a como esta explicada por ah para que los que empecis podis entender la herencia
desde otro punto de vista.

7
Polimorfismo en Java (Parte I), con
ejemplos
https://jarroba.com/polimorfismo-en-java-parte-i-con-ejemplos/

El proyecto de este post lo puedes descargar pulsando AQUI.

El Polimorfismo es uno de los 4 pilares de la programacin orientada a


objetos (POO) junto con la Abstraccin, Encapsulacin y Herencia. Para entender
que es el polimorfismo es muy importante que tengis bastante claro el concepto de la
Herencia, por tanto recomendamos que veis la entrada en la que hablamos de la
Herencia: Herencia en Java, con ejemplos.

Para empezar con esta entrada, se ha de decir que el


trmino "Polimorfismo" es una palabra de origen griego que
significa "muchas formas". Este termino se utiliza en la POO para "referirse a la
propiedad por la que es posible enviar mensajes sintcticamente iguales
a objetos de tipos distintos". Como esta definicin quizs sea algo difcil de
entender, vamos a explicarla con el ejemplo que pusimos en la entrada de
la herencia en la que queramos simular el comportamiento que tendran los diferentes
integrantes de la seleccin espaola de ftbol; tanto los Futbolistas como el cuerpo
tcnico (Entrenadores, Masajistas, etc). Para este ejemplo nos vamos a basar en el
siguiente diagrama de clases:

8
NOTA: en este diagrama y en adelante no vamos a poner los constructores y mtodos
getter y setter con el fin de que el diagrama nos quede grande e intendible aunque
en un buen diagrama de clases deberan aparecer para respetar el principio de
encapsulacin de la POO

En este ejemplo vamos a tener una clase padre (SeleccinFutbol) en la que


tendremos los atributos y mtodos comunes a todos los integrantes que forman
la seleccin espaola de ftbol (Futbolistas, Entrenadores, Masajistas, etc.) y en
ella se van a implementar los mtodos del comportamiento "genrico" que
deben de tener todos los integrantes de la seleccin. Como ya dijimos en la
entrada de la herencia, la herencia no es ms que sacar "factor comn" del cdigo
que escribimos, as que los atributos y mtodos de la clase SeleccionFutbol los
tendrn tambin los objetos de las clases Futbolista, Entrenador y Masajista. Antes de
seguir vamos a mostrar el cdigo de la clase "SeleccionFutbol" para ver algunas
peculiaridades:

public abstract class SeleccionFutbol {

protected int id;

9
protected String nombre;

protected String apellidos;

protected int edad;

// constructores, getter y setter

public void viajar() {

System.out.println("Viajar (Clase Padre)");

public void concentrarse() {

System.out.println("Concentrarse (Clase Padre)");

// IMPORTANTE -> METODO ABSTRACTO => no se implementa en la clase abstra


cta pero si en la clases hijas

public abstract void entrenamiento();

public void partidoFutbol() {

System.out.println("Asiste al Partido de Ftbol (Clase Padre)");

Lo primero que nos debe de llamar la atencin al ver este cdigo es que
utilizamos dos veces la palabra reservada "abstract". Esta palabra nos indica que la
clase "SeleccionFutbol" es una clase abstracta y las clases abstractas no se
pueden instanciar, por tanto nunca podremos hacer un "new SeleccionFutbol()". Otra
cosa que vemos es que tambin utilizamos la palabra reservada abstract en un
mtodo (en el mtodo entrenamiento). Esto quiere decir que todas las clases hijas
de la clase "SeleccionFubol" tienen que tener implementado ese mtodo
obligatoriamente. Por tanto con esto que se acaba de contar y diciendo que la

10
palabra "Polimorfismo" significa "muchas formas", podis deducir que la clase
"SeleccionFutbol" es una clase que puede adoptar diferentes formas y en este
ejemplo puede adoptar las formas de "Futbolista", "Entrenador" y "Masajista".

Como vemos un "Entrenador", un "Futbolista" y un "Masajista" pertenecen a la


misma clase padre y por eso se instancian diciendo que es una SeleccionFutbol y son
nuevos objetos de las clases hijas. Por otro lado vemos que no se pueden crear
objetos de una clase abstracta, por tanto el crearnos el objeto "casillas" nos da un
error.

Y ahora si hemos dicho que hemos definido en la clase padre un mtodo


abstracto que es obligatorio implementar en las clases hijas Como lo hacemos?.
Bueno vamos por partes. Una cosa muy buena que tiene la herencia y el
polimorfismo, es que las clases hijas no solo heredan los mtodos (o la
implementacin de los mtodos) de las clases padre, sino que las clases hijas se
pueden especializar. Esto significa que una clase hija puede "redefinir" los mtodos
de su clase padre; es decir, que se puede volver a escribir ese mtodo y de ahi la
especializacin. Para ello vamos a ver la implementacin de las clases hijas:

public class Futbolista extends SeleccionFutbol {

private int dorsal;

private String demarcacion;

// constructor, getter y setter

@Override

public void entrenamiento() {

System.out.println("Realiza un entrenamiento (Clase Futbolista)");

11
}

@Override

public void partidoFutbol() {

System.out.println("Juega un Partido (Clase Futbolista)");

public void entrevista() {

System.out.println("Da una Entrevista");

public class Entrenador extends SeleccionFutbol {

private int idFederacion;

// constructor, getter y setter

@Override

public void entrenamiento() {

System.out.println("Dirige un entrenamiento (Clase Entrenador)");

@Override

public void partidoFutbol() {

System.out.println("Dirige un Partido (Clase Entrenador)");

12
public void planificarEntrenamiento() {

System.out.println("Planificar un Entrenamiento");

public class Masajista extends SeleccionFutbol {

private String titulacion;

private int aniosExperiencia;

// constructor, getter y setter

@Override

public void entrenamiento() {

System.out.println("Da asistencia en el entrenamiento (Clase Masajista)");

public void darMasaje() {

System.out.println("Da un Masaje");

Como vemos en el cdigo todas las clases hijas tienen implementada el


mtodo "entrenamiento()" ya que como dijimos al tenerlo en la clase padre como
mtodo abstracto, es obligatorio que todas las clases hijas tengan ese mtodo. Por
otro lado observamos en el cdigo que encima del mtodo "entrenamiento()" y otros
mtodos, tenemos la etiqueta "@Override". Esta etiqueta sirve para indicar en el
cdigo que estamos "re-escribiendo o especializando" un mtodo que se
encuentra en la clase padre y que queremos redefinir en la clase hija. Si os fijis
esta etiqueta solo y exclusivamente esta en los mtodos de las clases hijas que
tenemos definida en la clase padre, por tanto cuando se llame a esos mtodos, las
clases hijas ejecutaran el mtodo redefinido en la clase hija y las que no lo hayan

13
redefinido se ejecutar es mtodo de la clase padre. En la siguiente imagen vemos
como hacemos estas especializaciones:

Con todo esto ya podemos empezar a ejecutar el programa que simular el


comportamiento de los integrantes de la seleccin espaola y ver las diferentes
formas que adoptan cada uno de los integrantes de la seleccin. Para ello
empecemos mostrando el siguiente fragmento de cdigo:

public class Main {

// ArrayList de objetos SeleccionFutbol. Idenpendientemente de la clase


hija a la que pertenezca el objeto

public static ArrayList<SeleccionFutbol> integrantes = new ArrayList<Sel


eccionFutbol>();

public static void main(String[] args) {

14
SeleccionFutbol delBosque = new Entrenador(1, "Vicente", "Del B
osque", 60, 28489);

SeleccionFutbol iniesta = new Futbolista(2, "Andres", "Iniesta"


, 29, 6, "Interior Derecho");

SeleccionFutbol raulMartinez = new Masajista(3, "Ral", "Martin


ez", 41, "Licenciado en Fisioterapia", 18);

integrantes.add(delBosque);

integrantes.add(iniesta);

integrantes.add(raulMartinez);

// CONCENTRACION

System.out.println("Todos los integrantes comienzan una concent


racion. (Todos ejecutan el mismo mtodo)");

for (SeleccionFutbol integrante : integrantes) {

System.out.print(integrante.getNombre() + " " + integra


nte.getApellidos() + " -> ");

integrante.concentrarse();

// VIAJE

System.out.println("nTodos los integrantes viajan para jugar un


partido. (Todos ejecutan el mismo mtodo)");

for (SeleccionFutbol integrante : integrantes) {

System.out.print(integrante.getNombre() + " " + integra


nte.getApellidos() + " -> ");

integrante.viajar();

.........

15
}

Como vemos nos hemos creado tres objetos de la clase SeleccionFutbol que
adoptan una de las tres formas que pueden adaptar (Entrenador, Futbolista y
Masajista) y los metemos en un ArrayList de objetos de la clase SeleccionFutbol.
Ahora al ejecutar este fragmento de cdigo vamos a ver que todos tienen el mismo
comportamiento a la hora de "concentrarse()" y "viajar()", por tanto ejecutarn el
mtodo de la clase padre:

Todos los integrantes comienzan una concentracion. (Todos ejecutan el mismo mto
do)
Vicente Del Bosque -> Concentrarse (Clase Padre)
Andres Iniesta -> Concentrarse (Clase Padre)
Ral Martinez -> Concentrarse (Clase Padre)

Todos los integrantes viajan para jugar un partido. (Todos ejecutan el mismo mt
odo)
Vicente Del Bosque -> Viajar (Clase Padre)
Andres Iniesta -> Viajar (Clase Padre)
Ral Martinez -> Viajar (Clase Padre)

Hasta el momento nada nuevo y sorprendente, pero ahora vamos a ver como
cada uno de los integrante al lanzarse los mismos mtodos ("entrenamiento()" y
"partidoFutbol()") tienen un comportamiento diferente:

........

// ENTRENAMIENTO

System.out.println("nEntrenamiento: Todos los integrantes tienen su funcin en u


n entrenamiento (Especializacin)");

for (SeleccionFutbol integrante : integrantes) {

System.out.print(integrante.getNombre() + " " + integrante.getApellidos(


) + " -> ");

integrante.entrenamiento();

16
// PARTIDO DE FUTBOL

System.out.println("nPartido de Ftbol: Todos los integrantes tienen su funcin


en un partido (Especializacin)");

for (SeleccionFutbol integrante : integrantes) {

System.out.print(integrante.getNombre() + " " + integrante.getApellidos(


) + " -> ");

integrante.partidoFutbol();

........

Vemos el resultado al ejecutar este fragmento de cdigo:

Entrenamiento: Todos los integrantes tienen su funcin en un entrenamiento (Espe


cializacin)
Vicente Del Bosque -> Dirige un entrenamiento (Clase Entrenador)
Andres Iniesta -> Realiza un entrenamiento (Clase Futbolista)
Ral Martinez -> Da asistencia en el entrenamiento (Clase Masajista)

Partido de Ftbol: Todos los integrantes tienen su funcin en un partido (Especi


alizacin)
Vicente Del Bosque -> Dirige un Partido (Clase Entrenador)
Andres Iniesta -> Juega un Partido (Clase Futbolista)
Ral Martinez -> Asiste al Partido de Ftbol (Clase Padre)

En este caso vemos que todos los integrantes ejecutan el mtodo


"entrenamiento()" de forma diferente ya que al ser este mtodo abstracto en la clase
padre, les forzamos a las clases hijas a que implementen ese mtodo. Por el contrario
al ejecutar el mtodo "partidoFutbol()" vemos que el objeto de la clase Masajista utiliza
el mtodo implementado en la clase padre y en cambio los objetos de la clase
Futbolista y Entrenador ejecutan sus mtodo "re-implementados o especializados"
que se volvieron a escribir en sus clases.

Por ltimo vamos a ver que cada uno de los objetos puede ejecutar mtodos
propios que solamente ellos los tienen como son el caso de
"planificarEntrenamiento(), entrevista() y darMasaje()" que solo los pueden ejecutar
objetos de la clase Entrenador, Futbolista y Masajista respectivamente:

17
........

// PLANIFICAR ENTRENAMIENTO

System.out.println("nPlanificar Entrenamiento: Solo el entrenador tiene el mtod


o para planificar un entrenamiento:");

System.out.print(delBosque.getNombre() + " " + delBosque.getApellidos() + " -> "


);

((Entrenador) delBosque).planificarEntrenamiento();

// ENTREVISTA

System.out.println("nEntrevista: Solo el futbolista tiene el mtodo para dar una


entrevista:");

System.out.print(iniesta.getNombre() + " " + iniesta.getApellidos() + " -> ");

((Futbolista) iniesta).entrevista();

// MASAJE

System.out.println("nMasaje: Solo el masajista tiene el mtodo para dar un masaj


e:");

System.out.print(raulMartinez.getNombre() + " " + raulMartinez.getApellidos() +


" -> ");

((Masajista) raulMartinez).darMasaje();

........

Como resultado de la ejecucin de este fragmento de cdigo tenemos lo


siguiente:

Planificar Entrenamiento: Solo el entrenador tiene el mtodo para planificar un


entrenamiento:
Vicente Del Bosque -> Planificar un Entrenamiento

Entrevista: Solo el futbolista tiene el mtodo para dar una entrevista:


Andres Iniesta -> Da una Entrevista

18
Masaje: Solo el masajista tiene el mtodo para dar un masaje:
Ral Martinez -> Da un Masaje

CONCLUSIONES Y ACLARACIONES:
Como hemos visto el polimorfismo es un concepto un poco ms avanzado que
la herencia y puede ser muy util a la hora de jerarquizar y querer dar un patrn de
comportamiento comn a una serie de objetos que heredan de la misma clase. En
esta entrada no hemos visto todo lo referente al polimorfismo ya que nos quedara ver
un concepto un poco ms avanzado en Java (y en otros lenguajes tambin) como son
las "Interface" (clases abstractas puras) de las cuales hablaremos en otra entrada
para terminar de ver lo que es el polimorfismo.

Por ltimo es muy probable para los que estis empezando con la POO que no
veis mucho sentido a esto del polimorfismo y al principio es normal. Solo os debo de
decir que a base de experiencia se le encuentra sentido al polimorfismo, por tanto si
teneis que hacer alguna prctica en la universidad o lo que sea en la que tengais que
usar el polimorfismo intentar entenderlo y hacer lo que os pidan porque entenderlo
100% es complicado y se requiere de experiencia para ello.

https://jarroba.com/polimorfismo-en-java-interface-parte-ii-con-ejemplos/

Polimorfismo en Java -Interface-


(Parte II), con ejemplos

El proyecto de este post lo puedes descargar pulsando AQUI.

En esta entrada vamos a continuar hablando de polimorfismo y en concreto


vamos a explicar las "Interface" y como siempre lo vamos ha hacer con un ejemplo.
Para entender lo que vamos a contar en esta entrada es imprescindible que sepais
que es la herencia y el polimorfismo, por tanto sino teneis muy claros estos conceptos
recomendamos que mireis los siguientes tutoriales en los que hablamos sobre ello:

19
Herencia -> Herencia en Java, con ejemplos
Polimorfismo -> Polimorfismo en Java (Parte I), con ejemplos

El concepto de Interface lleva un paso ms alla el concepto de una clase


abstracta en la que vimos que una clase abstracta es una clase que no se puede
instanciar (crear un objeto de esa clase) pero si se pueden definir atributos e
implementar mtodos en ella para que sus clases hijas los puedan utilizar. Pues
bien una Interface es una clase abstracta pura en la que todos sus mtodos son
abstractos y por tanto no se pueden implementar en la clase Interface. Mucho
podreis pensar para que vale una clase abstracta pura en la que no se permiten
implementar mtodos y que encima en las clases hijas de esa interface tengan que
tener "si o si" implementados estos mtodos; pues bien, las Interfaces sirven para
establecer la forma que debe de tener una clase. Un ejemplo que hay en Java
sobre Interace es la Interface Map. En la entrada "Map en Java, con ejemplos", vimos
que habia diferentes tipos de Map; en concreto los HashMap, TreeMap
y LinkedHashMap, lo que quiere decir que todas las clases Map deben de tener
implementadas a su manera los mismo mtodos como el "put()", "get()", "remove()",
etc. y asi lo vimos en esta entrada en la que un HashMap inserta los datos de manera
diferente a un TreeMap y al LinkedHashMap. Por tanto vemos como se ha establecido
una forma comn que deben de respetar todos los Maps de Java.

Por otro lado se ha de decir que una Interface no se pueden definir atributos
salvo que estos sean estaticos o constantes; es decir, "static" o "final".

Siguiendo con los ejemplos que hemos estado poniendo en las entradas de
la Herencia y el Polimorfismo, vamos a ver un ejemplo en el que simularemos el
comportamiento que tendran los diferentes integrantes de la seleccin espaola de
ftbol; tanto los Futbolistas como el cuerpo tcnico (Entrenadores, Masajistas, etc).
Para este ejemplo nos vamos a basar en el siguiente diagrama de clases:

20
Lo primero que vemos es la clase "IntegranteSeleccionFutbol" que es una
Interface en la que tiene definido cuatro mtodos (es decir una clase abstracta pura).
Como se ha dicho en esta clase solo se definen los mtodos pero no se implementan;
as que a nivel de cdigo la clase quedaria de la siguiente manera:

public interface IntegranteSeleccionFutbol {

void concentrarse();

void viajar();

void entrenar();

21
void jugarPartido();

Lo siguiente que vemos en el diagrama de clases es la


clase "SeleccionFutbol" que es una clase abstracta que utiliza (implements) la
Interface "IntegranteSeleccionFutbol". Al ser esta una clase abstracta no se puede
instanciar y por tanto en ella no es necesario implementar los mtodos de la
"Interfece"; pero si ser obligatorio implementarlo en sus clases hijas (Futbolista,
Entrenador y Masajista). Para que veamos bien el uso de las interfaces, vamos ha
hacer primero una "chapuzilla" para entender su utilizacin. Lo que vamos ha hacer es
"no implementar los mtodos de la interface en la clase abstracta SeleccionFutbol"
con el fin de que veamos que en las clases hijas nos van a exigir que implementemos
los mtodos de la interface. Para ello la clase abstracta quedara de la siguiente forma
(sin ningn mtodo implementado):

public abstract class SeleccionFutbol implements IntegranteSeleccionFutbol {

protected int id;

protected String nombre;

protected String apellidos;

protected int edad;

public SeleccionFutbol() {

public SeleccionFutbol(int id, String nombre, String apellidos, int edad


) {

this.id = id;

this.nombre = nombre;

this.apellidos = apellidos;

22
this.edad = edad;

// getter y setter

En este punto vemos una nueva palabra reservada como es la palabra


"implements" que quiere decir que la clase "SeleccionFutbol" debe ser una clase que
adopte la forma que tiene la Interface "IntegranteSeleccionFutbol"; es decir, que debe
tener implementados los mtodos de la Interface. En este caso al ser una clase
abstracta las podemos implementar ahi (si queremos) o en las clases hijas
(obligatoriamente sino las implementamos en la clase padre), por eso el ejemplo que
ponemos es para ver como el compilador nos exigir que esos mtodos estn
implementados en las clases hijas.

Por tanto sino implementamos los mtodos en la clase padre


("SeleccionFutbol") y nos vamos a cualquiera de las clases hijas (por ejemplo la de
futbolista) vemos como nos exigen que implementemos esos mtodos:

Vemos en la clase futbolista (en el IDE de Eclipse) que nos da un error y como
solucin nos dice que tenemos que implementar los mtodos "concentrarse()",
"viajar()", etc. Si en Eclipse seleccionamos una de las opciones para solucionar el
error, vemos que nos da la opcin de "Aadir los mtodos no implementados" (add
unimplemented methods):

23
Si seleccionamos esa opcin vemos como en Eclipse nos implementa los
mtodos de la Interface de forma automtica:

24
Como ya hemos visto que nos exigen implementar los mtodos en la Interface
en las clases hijas, ahora vamos ha hacer las cosas bien y vamos a implementar los
mtodos de la Interface en la clase padre ("SeleccionFutbol") para que solamente
haya que implementar los mtodos que queramos especializarlos en las clases hijas.
Por tanto la clase "SeleccionFutbol" bien implementada quedaria de la siguiente
forma:

public abstract class SeleccionFutbol implements IntegranteSeleccionFutbol {

protected int id;

protected String nombre;

25
protected String apellidos;

protected int edad;

// Constructor, getter y setter

public void concentrarse() {

System.out.println("Concentrarse (Clase Padre)");

public void viajar() {

System.out.println("Viajar (Clase Padre)");

public void entrenar() {

System.out.println("Entrenar (Clase Padre)");

public void jugarPartido() {

System.out.println("Asiste al Partido de Ftbol (Clase Padre)")


;

Y en las clases hijas solo implementaremos los mtodos de la clase padre que
queramos redefinir, quedando las clases hijas de la siguiente forma (recordar que la
etiqueta "@Override" significa que ese mtodo esta siendo redefinido)::

26
public class Futbolista extends SeleccionFutbol {

private int dorsal;

private String demarcacion;

// Constructor, getter y setter

@Override

public void entrenar() {

System.out.println("Realiza un entrenamiento (Clase Futbolista)


");

@Override

public void jugarPartido() {

System.out.println("Juega un Partido (Clase Futbolista)");

public void entrevista() {

System.out.println("Da una Entrevista");

public class Entrenador extends SeleccionFutbol {

private int idFederacion;

// Constructor, getter y setter

27
@Override

public void entrenar() {

System.out.println("Dirige un entrenamiento (Clase Entrenador)"


);

@Override

public void jugarPartido() {

System.out.println("Dirige un Partido (Clase Entrenador)");

public void planificarEntrenamiento() {

System.out.println("Planificar un Entrenamiento");

public class Masajista extends SeleccionFutbol {

private String titulacion;

private int aniosExperiencia;

// Constructor, getter y setter

@Override

public void entrenar() {

28
System.out.println("Da asistencia en el entrenamiento (Clase Ma
sajista)");

public void darMasaje() {

System.out.println("Da un Masaje");

Llegados a este punto ya tenemos implementada las misma funcionalidad que


hicimos en la entrada de Polimorfismo en Java (Parte I), con ejemplos pero diseada
e implementada de otra forma, as que vamos a poner el cdigo que escribimos para
esa entrada y el resultado de la ejecucin del mismo para que podais ver el resultado:

public class Main {

// ArrayList de objetos SeleccionFutbol. Idenpendientemente de la clase


hija a la que pertenezca el objeto

public static ArrayList integrantes = new ArrayList();

public static void main(String[] args) {

SeleccionFutbol delBosque = new Entrenador(1, "Vicente", "Del B


osque", 60, 28489);

SeleccionFutbol iniesta = new Futbolista(2, "Andres", "Iniesta"


, 29, 6, "Interior Derecho");

SeleccionFutbol raulMartinez = new Masajista(3, "Ral", "Martin


ez", 41, "Licenciado en Fisioterapia", 18);

integrantes.add(delBosque);

integrantes.add(iniesta);

29
integrantes.add(raulMartinez);

// CONCENTRACION

System.out.println("Todos los integrantes comienzan una concent


racion. (Todos ejecutan el mismo mtodo)");

for (SeleccionFutbol integrante : integrantes) {

System.out.print(integrante.getNombre() + " " + integra


nte.getApellidos() + " -> ");

integrante.concentrarse();

// VIAJE

System.out.println("nTodos los integrantes viajan para jugar un


partido. (Todos ejecutan el mismo mtodo)");

for (SeleccionFutbol integrante : integrantes) {

System.out.print(integrante.getNombre() + " " + integra


nte.getApellidos() + " -> ");

integrante.viajar();

// ENTRENAMIENTO

System.out.println("nEntrenamiento: Todos los integrantes tiene


n su funcin en un entrenamiento (Especializacin)");

for (SeleccionFutbol integrante : integrantes) {

System.out.print(integrante.getNombre() + " " + integra


nte.getApellidos() + " -> ");

integrante.entrenar();

// PARTIDO DE FUTBOL

30
System.out.println("nPartido de Ftbol: Todos los integrantes t
ienen su funcin en un partido (Especializacin)");

for (SeleccionFutbol integrante : integrantes) {

System.out.print(integrante.getNombre() + " " + integra


nte.getApellidos() + " -> ");

integrante.jugarPartido();

// PLANIFICAR ENTRENAMIENTO

System.out.println("nPlanificar Entrenamiento: Solo el entrenad


or tiene el mtodo para planificar un entrenamiento:");

System.out.print(delBosque.getNombre() + " " + delBosque.getApe


llidos() + " -> ");

((Entrenador) delBosque).planificarEntrenamiento();

// ENTREVISTA

System.out.println("nEntrevista: Solo el futbolista tiene el m


todo para dar una entrevista:");

System.out.print(iniesta.getNombre() + " " + iniesta.getApellid


os() + " -> ");

((Futbolista) iniesta).entrevista();

// MASAJE

System.out.println("nMasaje: Solo el masajista tiene el mtodo


para dar un masaje:");

System.out.print(raulMartinez.getNombre() + " " + raulMartinez.


getApellidos() + " -> ");

((Masajista) raulMartinez).darMasaje();

31
}

Como resultado a la ejecucin de este programa tenemos lo siguiente:

Todos los integrantes comienzan una concentracion. (Todos ejecutan el mismo mto
do)
Vicente Del Bosque -> Concentrarse (Clase Padre)
Andres Iniesta -> Concentrarse (Clase Padre)
Ral Martinez -> Concentrarse (Clase Padre)

Todos los integrantes viajan para jugar un partido. (Todos ejecutan el mismo mt
odo)
Vicente Del Bosque -> Viajar (Clase Padre)
Andres Iniesta -> Viajar (Clase Padre)
Ral Martinez -> Viajar (Clase Padre)

Entrenamiento: Todos los integrantes tienen su funcin en un entrenamiento (Espe


cializacin)
Vicente Del Bosque -> Dirige un entrenamiento (Clase Entrenador)
Andres Iniesta -> Realiza un entrenamiento (Clase Futbolista)
Ral Martinez -> Da asistencia en el entrenamiento (Clase Masajista)

Partido de Ftbol: Todos los integrantes tienen su funcin en un partido (Especi


alizacin)
Vicente Del Bosque -> Dirige un Partido (Clase Entrenador)
Andres Iniesta -> Juega un Partido (Clase Futbolista)
Ral Martinez -> Asiste al Partido de Ftbol (Clase Padre)

Planificar Entrenamiento: Solo el entrenador tiene el mtodo para planificar un


entrenamiento:
Vicente Del Bosque -> Planificar un Entrenamiento

Entrevista: Solo el futbolista tiene el mtodo para dar una entrevista:


Andres Iniesta -> Da una Entrevista

32
Masaje: Solo el masajista tiene el mtodo para dar un masaje:
Ral Martinez -> Da un Masaje

CONCLUSIONES Y ACLARACIONES:
Como hemos visto el concepto de la Interface va un paso ms alla en lo
referente al concepto de la clase abstracta. Es una muy buena prctica de diseo la
utilizacin de clases Interface para definir clases que tengan una misma forma,
aunque en ellas realicen comportamientos distintos.

Al igual que comentamos en las conclusiones de la entrada del polimorfismo,


es muy probable que los que empeceis con la POO no le veais mucho sentido al tema
de las clases Interface, as que no os preocupeis si eso es asi porque estos conceptos
se consolidan a base de experiencia y de ir adquiriendo ms conocimientos de
arquitectura y diseo del software.

33

Potrebbero piacerti anche