Llegamos al último post del bloque de
Programación Genérica espero que os haya quedado claro, sino, pues ya sabéis
que las dudas las podéis enviar a través de los comentarios del blog o
escribiendo un correo a amizba@gmail.com
La herencia no funciona igual con las
clases genéricas que con las clases ordinarias y este funcionamiento diferente
nos va a obligar a utilizar tipos comodín sobre todo a la hora de llamar a
métodos que han sido declarados dentro de una clase genérica.
Para ver la diferencia entre la
herencia entre las clases ordinarias y las clases orgánicas hay que remontarse
al apartado Todo Java:2.12 HERENCIA (empezandojava.blogspot.com) de
la herencia en el que vimos un
ejemplo el cual teníamos una clase llamada Empleado
y una clase Jefe, la clase Jefe podía heredar de la clase Empleado utilizado el método sustitución, es decir, empleando la
frase “Es un…” Un jefe es un
empleado, sin embargo, la clase Empleado no puede heredar de la clase Jefe
porque un empleado no siempre es un jefe.
Pues esto con las clases genéricas no
funciona igual, si tenemos una clase de tipo genérico Empleado y otra clase de
tipo genérico Jefe no existe relación de herencia para solucionar esto existen
los tipos comodín.
Todo esto es mejor verlo sobre la
práctica vamos a trabajar con cuatro clases algunas ya las hemos visto en
apartados anteriores, la clase Pareja:
package clases_propias;
public class Pareja<T>
{
public Pareja() {
primero = null;
}
public void setPrimero(T nuevoValor) {
primero=nuevoValor;
}
public T getPrimero()
{
return primero;
}
private T primero;
}
HerenciaGenericos que es la que contiene el método
principal main:
package clases_propias;
public class
HerenciaGenericos {
public static void main(String[] args) {
// TODO
Auto-generated method stub
}
}
La clase Empleado:
package clases_propias;
public class Empleado
{
public Empleado(String
nombre, int edad, double salario) {
this.nombre=nombre;
this.edad=edad;
this.salario=salario;
}
public String dameDatos() {
return "El empleado
se llama "+nombre+" tiene "+edad+" años y tiene un salario de "+salario+" euros.";
}
private String nombre;
private int edad;
private double salario;
}
Y la clase Jefe:
package clases_propias;
public class Jefe extends Empleado{
public Jefe(String nombre, int edad, double salario) {
super(nombre, edad, salario);
}
double incentivo (double inc) {
return inc;
}
}
Nos vamos a la clase HerenciaGenericos y dentro del método
main manejando la clase Empleado, la
clase Jefe y el principio de
sustitución “Es un…” podemos crear
una instancia perteneciente a la clase Empleado
y pasarle los parámetros:
package clases_propias;
public class HerenciaGenericos
{
public static void main(String[] args) {
Empleado
administrativa = new Empleado("Eva", 52, 12500);
}
}
Creamos una instancia de
la clase Jefe:
package clases_propias;
public class
HerenciaGenericos {
public static void main(String[] args) {
Empleado
administrativa = new Empleado("Eva", 52, 12500);
Jefe director
= new Jefe("Antonio", 25, 22500);
}
}
Gracias al principio de
sustitución “Es un…” podemos crear
una variable de tipo Empleado y va a
ser igual a director:
package clases_propias;
public class
HerenciaGenericos {
public static void main(String[] args) {
Empleado
administrativa = new Empleado("Eva", 52, 12500);
Jefe
director = new Jefe("Antonio", 25, 22500);
Empleado nuevoEmpleado = director;
}
}
Gracias a este principio
un empleado puede ser un Jefe, esto es la herencia en Java.
Sin embargo, cuando son
clases genéricas no es así como funciona la herencia. Con clases genéricas
sería de la siguiente forma creamos la instancia Pareja de tipo Empleado al que le vamos a dar el nombre de administrativa:
package clases_propias;
public class
HerenciaGenericos {
public static void main(String[] args) {
/*Empleado
administrativa = new Empleado("Eva", 52, 12500);
Jefe director = new Jefe("Antonio",
25, 22500);
Empleado nuevoEmpleado = director;*/
Pareja<Empleado> administrativa = new Pareja<Empleado>();
}
}
Hacemos lo mismo pero con
el tipo Jefe:
package clases_propias;
public class
HerenciaGenericos {
public static void main(String[] args) {
/*Empleado
administrativa = new Empleado("Eva", 52, 12500);
Jefe director = new Jefe("Antonio",
25, 22500);
Empleado nuevoEmpleado = director;*/
Pareja<Empleado>
administrativa = new
Pareja<Empleado>();
Pareja<Jefe> director
= new Pareja<Jefe>();
}
}
Si intentamos aplicar el
principio de sustitución:
package clases_propias;
public class
HerenciaGenericos {
public static void main(String[] args) {
/*Empleado
administrativa = new Empleado("Eva", 52, 12500);
Jefe director = new Jefe("Antonio",
25, 22500);
Empleado nuevoEmpleado = director;*/
Pareja<Empleado>
administrativa = new
Pareja<Empleado>();
Pareja<Jefe>
director = new
Pareja<Jefe>();
Pareja<Empleado> nuevoEmpleado
= director;
}
}
Vemos que nos marca un error:
Y si nos posicionamos con el puntero del ratón sobre el error:
No se puede convertir Pareja de tipo
Jefe a Pareja de tipo Empleado. Vamos a ver cómo solucionarlo, vamos al código
de la clase genérica Pareja y nos
vamos a crear un método que nos imprima por consola un empleado en concreto.
public static void
imprimirTrabajador(Pareja<Empleado> p) {
}
Le hemos pasado un objeto Pareja de
tipo Empleado al que hemos llamado p.
Lo que va a hacer este método es devolvernos el empleado:
public static void
imprimirTrabajador(Pareja<Empleado> p) {
Empleado
primero = p.getPrimero();
System.out.println(primero);
}
En la clase principal HerenciaGenericos vamos a llamar a este método para tipo Empleado y para tipo Jefe, si nos fijamos para el tipo Jefe da un error de compilación:
Esta es la restricción que hay en las clases genéricas utilizando el principio de sustitución. Si vemos el error nos lo indica claramente:
Para solucionar esto se utilizan los
tipos comodín se usan de la siguiente forma, en el método si queremos que sea
aplicable para la clase Empleado y sus subclases, por ejemplo, Jefe:
public static void
imprimirTrabajador(Pareja<?
extends Empleado> p) {
Donde le pasamos en el argumento dentro de los corchetes angulares la cláusula ? extends. Con esto y al guardar los cambios en Eclipse volvemos a la clase HerenciaGenericos y comprobamos que esa línea que nos marcaba error ya no nos lo marca.
Esto ha sido todo os espero en el
próximo bloque, muchas gracias por seguirme y hasta pronto!
16.3 MÉTODOS GENÉRICOS <<
>> 17.1 INTRODUCCIÓN THREADS