I need to store lots of objects that belong to different classes:
ClassA {...}
ClassA1 extends ClassA {...}
ClassA2 extends ClassA {...}
ClassA2a extends ClassA2 {...}
ClassB {...}
Now I need to find a way to store all these objects in a way that allows me to efficiently get all objects that belong to a particular class and its inherited child classes. For example, this imaginary code
getObjects(ClassA2)
would return a list of all stored objects that belong to ClassA2 or ClassA2a.
I believe a tree collection of some sort would be suitable, but I can't think of any way to implement it. Any ideas?
(Background: I am creating a simple java game, in which there's number of sprites that I need to manage, while some of those sprites share similar properties. When I check for events like collisions, I need to get all objects that extend EnemySprite and compare their coordinates with the player's sprite.)
Hierarchical inheritance is one of the types of inheritance where multiple child classes inherit the methods and properties of the same parent class. Hierarchical inheritance not only reduces the code length but also increases the code modularity.
On the basis of class, there can be three types of inheritance in java: single, multilevel and hierarchical.
Classes are organized into a singly rooted tree structure, called an inheritance hierarchy. Information (data and/or behavior) associated with one level of abstraction in a class hierarchy is automatically applicable to lower levels of the hierarchy.
In Java, the class hierarchy is tree like. In fact, not only is the hierarchy tree-like, Java provides a universal superclass called Object that is defined to be the root of the entire class hierarchy. Every class that is defined in a Java program implicitly extends the class Object.
There are several ways how to approach this. One would be, e.g., to generate strings like ParentClass1:ChildClass2:ChildClass1:
for every object and use them as a key to a TreeMap
or Trie
which you would then traverse.
Here is a simpler solution, though. The following class contains a map from class to all objects implementing it. The only trick is adding an object to all buckets where it belongs:
public class HierarchyMap {
private final Map<Class<?>, List<Object>> map = new HashMap<>();
public void add(Object o) {
Class<?> clazz = o.getClass();
while (clazz != Object.class) {
List<Object> list = map.computeIfAbsent(clazz, c -> new ArrayList<>());
list.add(o);
clazz = clazz.getSuperclass();
}
}
public List<Object> getByClass(Class<?> clazz) {
return map.get(clazz);
}
}
Usage:
public class A { public String toString() { return "A"; } }
public class B extends A{ public String toString() { return "B"; } }
public class C extends B { public String toString() { return "C"; } }
// ...
HierarchyMap hierarchyMap = new HierarchyMap();
hierarchyMap.add(new A());
hierarchyMap.add(new B());
hierarchyMap.add(new C());
System.out.println(hierarchyMap.getByClass(B.class));
// prints [B, C]
Mifeet seems to have literally answered your question, but I suspect you shouldn't be trying to do what you're proposing to do. Why not just have a master list of all objects that might collide, then filter it as needed using instanceof
?
This is conceptually a lot easier than what you're proposing to do, and the efficiency impact probably isn't that big. (In general, you will probably hear or have heard the mantra: Don't try to optimize too early.)
To be honest, I'm not sure you realize that filtering for EnemySprite
will get you all object instances of its subclasses as well.
public class CollisionChecker(){
private List colliders;
public CollisionChecker(){
colliders = new ArrayList<Object>();
}
public void addCollider(Object o){
colliders.add(o);
}
public List<EnemySprite> getEnemySprites(){
List<EnemySprite> enemies = new ArrayList<EnemySprite>();
for (Object o : colliders)
if (o instanceof EnemySprite)
enemies.add((EnemySprite)o);
return enemies;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With