La hiérarchie de l'arborescence est déjà implicitement défini par la déclaration des classes. Vous avez juste besoin de traverser une branche d'arbre via les appels chaînés getSuperclass()
au type que vous voulez rechercher. Les nœuds d'arbre (types de classe) peuvent alors être organisés en utilisant une simple carte de hachage.
Étant donné que la hiérarchie de type est statique, vous pouvez le définir comme ENUM
public enum ClassType{
HOMINOIDEA(HOMINOIDEA.class),
HOMINIDAE(HOMINIDAE.class),
HOMININAE(HOMININAE.class),
//and so on
UNKNOWN(null);
private static final Map<Class<?>, ClassType> typesMap = new HashMap<>();
public final Class<?> type;
static{
for (ClassType classType : EnumSet.allOf(ClassType.class)){
if(classType.type != null){
typesMap.put(classType.type, classType);
}
}
}
private ClassType(Class<?> type){
this.type = type;
}
public static ClassType getClassTypeOf(Class<?> type){
for(Class<?> lookupType = type; lookupType != null; lookupType = lookupType.getSuperclass()){
ClassType classType = typesMap.get(lookupType);
if(classType != null){
return classType;
}
}
return UNKNOWN;
}
}
puis cartographier les types de classes aux actions:
public static void main(String[] args){
EnumMap<ClassType, Action> actionMap = new EnumMap<>(ClassType.class);
actionMap.put(ClassType.HOMININAE, new HomininaeAction());
Homininae h = new Homininae();
actionMap.get(ClassType.getClassTypeOf(h)); //action associated with homininaes
}
Voici un autre dans certains termes version plus dynamique
public class ActionDispatcher {
private final Map<Class<?>, Consumer<?>> actionMap = new HashMap<>();
public <T> void registerAction(Class<T> type, Consumer<? super T> action){
actionMap.put(type, action);
}
@SuppressWarnings("unchecked")
public void dispatchActionFor(Object object){
Consumer<Object> action = ((Consumer<Object>)getActionFor(object.getClass()));
if(action != null){
action.accept(object);
}
}
private Consumer<?> getActionFor(Class<?> type){
for(Class<?> lookupType = type; lookupType != null; lookupType = lookupType.getSuperclass()){
Consumer<?> action = actionMap.get(lookupType);
if(action != null){
return action;
}
}
return null;
}
//demo
public static void main(String[] args){
ActionDispatcher dispatcher = new ActionDispatcher();
dispatcher.registerAction(Number.class, n -> System.out.println("number: " + n));
dispatcher.registerAction(Double.class, d -> System.out.println("double: " + d));
dispatcher.registerAction(String.class, s -> System.out.println("first char: " + s.charAt(0)));
dispatcher.registerAction(Object.class, o -> System.out.println("object: " + o));
dispatcher.dispatchActionFor(new Integer(3));
dispatcher.dispatchActionFor(new Double(3.0));
dispatcher.dispatchActionFor("string");
dispatcher.dispatchActionFor(new Thread());
}
}
La sortie de c'est:
number: 3
double: 3.0
first char: s
object: Thread[Thread-0,5,main]
La solution que j'ai à l'esprit est un arbre qui traverse de tuples de type et de l'action associée. – mike
Voulez-vous vérifier le type d'un objet donné? Pouvez-vous nous donner un exemple de code? –
Je ne suis pas certain de comprendre. Si vous avez des objets appartenant à la hiérarchie classe/type ci-dessus et des méthodes représentant des actions, l'appel de ces méthodes sur les objets appellera automatiquement l'action la plus spécifique. – user152468