Herencia Polimorfismo
Herencia Polimorfismo
Herencia Polimorfismo
https://jarroba.com/herencia-en-la-programacion-orientada-a-objetos-ejemplo-en-java/
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:
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:
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:
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/
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
9
protected String nombre;
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".
@Override
11
}
@Override
@Override
@Override
12
public void planificarEntrenamiento() {
System.out.println("Planificar un Entrenamiento");
@Override
System.out.println("Da un Masaje");
13
redefinido se ejecutar es mtodo de la clase padre. En la siguiente imagen vemos
como hacemos estas especializaciones:
14
SeleccionFutbol delBosque = new Entrenador(1, "Vicente", "Del B
osque", 60, 28489);
integrantes.add(delBosque);
integrantes.add(iniesta);
integrantes.add(raulMartinez);
// CONCENTRACION
integrante.concentrarse();
// VIAJE
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
integrante.entrenamiento();
16
// PARTIDO DE FUTBOL
integrante.partidoFutbol();
........
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
((Entrenador) delBosque).planificarEntrenamiento();
// ENTREVISTA
((Futbolista) iniesta).entrevista();
// MASAJE
((Masajista) raulMartinez).darMasaje();
........
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/
19
Herencia -> Herencia en Java, con ejemplos
Polimorfismo -> Polimorfismo en Java (Parte I), con ejemplos
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:
void concentrarse();
void viajar();
void entrenar();
21
void jugarPartido();
public SeleccionFutbol() {
this.id = id;
this.nombre = nombre;
this.apellidos = apellidos;
22
this.edad = edad;
// getter y setter
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:
25
protected String apellidos;
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 {
@Override
@Override
27
@Override
@Override
System.out.println("Planificar un Entrenamiento");
@Override
28
System.out.println("Da asistencia en el entrenamiento (Clase Ma
sajista)");
System.out.println("Da un Masaje");
integrantes.add(delBosque);
integrantes.add(iniesta);
29
integrantes.add(raulMartinez);
// CONCENTRACION
integrante.concentrarse();
// VIAJE
integrante.viajar();
// ENTRENAMIENTO
integrante.entrenar();
// PARTIDO DE FUTBOL
30
System.out.println("nPartido de Ftbol: Todos los integrantes t
ienen su funcin en un partido (Especializacin)");
integrante.jugarPartido();
// PLANIFICAR ENTRENAMIENTO
((Entrenador) delBosque).planificarEntrenamiento();
// ENTREVISTA
((Futbolista) iniesta).entrevista();
// MASAJE
((Masajista) raulMartinez).darMasaje();
31
}
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)
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.
33