Caso de estudio del problema que plantea:
\[\href{https://stackoverflow.com/q/4866873}{Charles}\\\]Cuando se usa el polimorfismo para tratar de eliminar los condicionales, lo que se está haciendo realmente es trasladar un problema de un sitio a otro, ya que los condicionales no llegan a desaparecer del todo, sino que se pasan a la zona de instanciación de las clases hijas que extienden mediante herencia a la clase abstracta padre.
Inicialmente, partimos de la siguiente situación inicial:
package main;
import java.util.Scanner;
public class MainClass4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner myObj = new Scanner(System.in);
System.out.println("Enter operation");
String operation = myObj.nextLine();
switch(operation){
case "view":
System.out.println("doSomething ViewAction");
break;
case "edit":
System.out.println("doSomething EditAction");
break;
case "sort":
System.out.println("doSomething SortAction");
break;
}
myObj.close();
}
}
Lo que buscamos es eliminar ese Switch de 3 condiciones, así que se nos ocurre crear 1 clase padre, abstracta, y 3 clases hijas que extiendan de la clase padre y anulen el método .doSomething(), como sigue:
Clase padre:
package polimorfismo;
public abstract class BaseAction {
public abstract void doSomething();
}
Clase hija 1:
package polimorfismo;
public class ViewAction extends BaseAction {
public ViewAction() {}
@Override
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething ViewAction");
}
}
Clase hija 2:
package polimorfismo;
public class EditAction extends BaseAction {
public EditAction() {}
@Override
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething EditAction");
}
}
Clase hija 3:
package polimorfismo;
public class SortAction extends BaseAction {
public SortAction() {}
@Override
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething SortAction");
}
}
En base al nuevo esquema, planteariamos esta nueva situación:
package main;
import java.util.Scanner;
import polimorfismo.*;
public class MainClass3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner myObj = new Scanner(System.in);
System.out.println("Enter operation");
String operation = myObj.nextLine();
BaseAction theAction = null;
switch (operation){
case "view":
theAction = new ViewAction();
break;
case "edit":
theAction = new EditAction();
break;
case "sort":
theAction = new SortAction();
break;
}
theAction.doSomething();
myObj.close();
}
}
Pero claro, nos damos cuenta de que no nos hemos podido desprender de los condicionales. Es más, lo único que hemos hecho es pasarlos a la zona de instanciación de las clases hijas.
Llegados a este punto, Java sí nos permite eliminar los condicionales que hemos trasladado a la zona de instanciación de las clases hijas mediante la reflexión, como sigue:
package main;
import java.lang.reflect.*;
import polimorfismo.*;
import java.lang.Class;
import java.util.Scanner;
public class MainClass {
public static void main(String[] args) throws Exception, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
Scanner myObj = new Scanner(System.in);
System.out.println("Enter operation");
String operation = myObj.nextLine();
operation = operation.substring(0, 1).toUpperCase()+operation.substring(1, operation.length()).toLowerCase();
String path = "polimorfismo."+operation+"Action";
Object object = Class.forName(path).getConstructor().newInstance();
BaseAction base = (BaseAction) object;
base.doSomething();
myObj.close();
}
}
Compilamos y probamos:
Enter operation
view
doSomething ViewAction