Saltar al contenido principal

Ejemplo de la importancia

Queremos crear un método en la clase Ordenar para implementar el método de ordenamiento de burbuja que ordene de mayor a menor una lista de objetos de cualquier clase.

Uso de tipos genéricos

En primer lugar, vamos a resolver el problema usando tipos genéricos. Por lo tanto, definimos e implementamos el método MetodoBurbuja donde el contenido de la lista es del tipo genérico T:

class Ordenar {
public static <T> void MetodoBurbuja(ArrayList<T> lista) {
boolean ordenada = false;
while (!ordenada) {
ordenada = true;
for (int i = 0; i < lista.size() - 1; i++) {
// En esta comparación necesitamos comparar si lista.get(i+1)
// es mayor que lista.get(i) para hacer el intercambio
if (/* Debemos introducir una condición aquí */) {
T aux = lista.get(i);
lista.set(i, lista.get(i + 1));
lista.set(i + 1, aux);
ordenada = false;
}
}
}
}
}

En la condición del if necesitamos poder realizar una comparación entre dos objetos de la clase genérica T. Como desconocemos cómo es la clase T, no sabemos cómo se va a hacer esa comparación.

Para solucionar este problema, podemos crear la interfaz Comparar. Esta sólo definirá un método esMayor para saber cuál es el mayor de dos objetos del tipo genérico T:

interface Comparar<T> {
boolean esMayor(T objeto);
}

Ahora sólo debemos modificar nuestro método MetodoBurbuja para que admita únicamente clases que implementen la interfaz Comparar<T> y utilizar el método esMayor para comparar los dos objetos de la clase genérica T:

class Ordenar {
// Estamos diciendo con extends que T tiene que implementar Comparar<T>
public static <T extends Comparar<T>> void MetodoBurbuja(ArrayList<T> lista) {
boolean ordenada = false;
while (!ordenada) {
ordenada = true;
for (int i = 0; i < lista.size() - 1; i++) {
// Ahora podemos comparar dos objetos
if (lista.get(i + 1).esMayor(lista.get(i))) {
T aux = lista.get(i);
lista.set(i, lista.get(i + 1));
lista.set(i + 1, aux);
ordenada = false;
}
}
}
}
}

Ahora para cualquier clase que creemos, si esta implementa Comparar<T> podremos ordenarla de mayor a menor utilizando nuestro método estático MetodoBurbuja.

Uso de polimorfismo

Podemos modificar para utilizar polimorfismo en lugar de tipos genéricos.

Para empezar modificamos la interfaz <Comparar> para que en el método esMayor reciba como parámetro un objeto de tipo Comparar.

interface Comparar {
boolean esMayor(Comparar objeto);
}

Ahora donde utilizamos polimorfismo es en el método MetodoBurbuja:

import java.util.ArrayList;

interface Comparar {
boolean esMayor(Comparar objeto);
}

class Ordenar {
public static void MetodoBurbuja(ArrayList<Comparar> lista) {
boolean ordenada = false;
while (!ordenada) {
ordenada = true;
for (int i = 0; i < lista.size() - 1; i++) {
if (lista.get(i + 1).esMayor(lista.get(i))) {
Comparar aux = lista.get(i);
lista.set(i, lista.get(i + 1));
lista.set(i + 1, aux);
ordenada = false;
}
}
}
}
}

Comparativa

En la siguiente tabla comparamos las dos implementaciones del método MetodoBurbuja:

  • La versión con tipos genéricos.
  • La versión sin tipos genéricos (uso de polimorfismo).
CriterioCon tipos genéricos (<T extends Comparar<T>>)Sin tipos genéricos (ArrayList<Comparar>)
Seguridad en compilación✅ Más seguro, evita errores de tipo en tiempo de ejecución.❌ Menos seguro, puede haber ClassCastException.
Flexibilidad✅ Funciona con cualquier clase que implemente Comparar<T>.❌ La lista puede contener objetos de distintos tipos, lo que puede generar errores.
Reutilización del código✅ Puede ser usado con diferentes clases sin cambios.❌ Puede ser menos reutilizable si los tipos no son compatibles.
Claridad y simplicidad❌ Más complejo al definir los tipos genéricos.✅ Más simple, evita la sintaxis de tipos genéricos.
Facilidad de mantenimiento✅ Más flexible y fácil de modificar en proyectos grandes.❌ Puede ser más difícil de depurar si hay errores de tipo.