You can use the search feature.
class Vehicle { T <T> lookup(Class<T> klazz) { return map.get(klazz);
This separates the classes. This requires a runtime check.
It uses delegation: local members implementing the lookup'ed class / interface.
Advantage:
You can get a class from Vehicle that can fly (Flyable) and dive (Diving). Flying can be implemented by an instance of a common class. You can even dynamically create opportunities (add wheels to the boat).
This is often better than implementing multiple interfaces, where fly() will either be a copy of the code or delegate to the Flyable field (with a common implementation class).
In particular, when using multiple interfaces / classes, you otherwise risk code on objects of the base class (Vehicle here) with cases and unsafe drops, forgetting if (x instanceof Boat) .
source share