6

Say I have a super class "Animal" and subclasses "Cat", Dog, Bird". Is there a way to have an array of subclass type rather than class instances with which I'll be able to instantiate instances of each possible subclass?

To simplify, I want this:

Pseudo code: For each possible subclass of "Animal": create an instance of that class.

How can I do that?

Edit: I don't want an array of instances of these subclasses, I want an array of object type.

11
  • 1
    it's not clear your question Commented Jul 19, 2013 at 3:02
  • 2
    What, you guys don't make Animal and Employee classes all the time? Commented Jul 19, 2013 at 3:06
  • 1
    It is not an assignment. I am using animals to make the problem easier to understand. @nachokk Basically I want to create an array of each possible different subclass of superclass "MySuperClass". Commented Jul 19, 2013 at 3:06
  • ii don't see the problem.. subclasses are made in static way so you know what are the subclasses just make a factory to create them.. Commented Jul 19, 2013 at 3:13
  • 1
    AFAIK, there is no way to programmatically discover all subclasses of a given type. Commented Jul 19, 2013 at 3:14

4 Answers 4

7

You can use Ploymorphism to achieve that.

Animal[] animalArray = new Animal[10];
animalArray[0] = new Dog();
animalArray[1] = new Cat();

Basically all subclasses of animal Class. When you want to retrieve the objects you can simply typecaset it

Dog dog = (Dog)animalArray[0];

To know the class you can simple use getClass() method. For example

    Animal[] animalArray = new Animal[10];
    animalArray[0] = new Dog();
    System.out.println(animalArray[0].getClass());

will print class Dog.

Sign up to request clarification or add additional context in comments.

1 Comment

@Jason Yes that's correct. You could have just edited it :)
3

After OP's comment
THERE IS NO WAY TO GET ALL SUBTYPES OF A CLASS even using reflection.
But you can do it by another way , you can say which is the only but longest way.

  • Get a list of names of all classes that exist on the class path
  • Load each class and test to see if it is a subclass or implementor of the desired class or interface



Answer before OP's comment

As your question is not clear yet but I guess you want to use array or Collection which will store all of the instances even it is the instance of superclass or subclass.
Then I guess you need to do like this.

List<Object> list = new ArrayList<Object>();
         list.add(new Cat());
         list.add(new Dog());
         list.add(new Animal());
         list.add(new Cat());

         for (int i = 0; i < list.size(); i++) {

             if(list.get(i) instanceof Cat){
                 System.out.println("Cat at "+i);
             }else if(list.get(i) instanceof Dog){
                 System.out.println("Dog at "+i);
             }else if(list.get(i) instanceof Animal){
                 System.out.println("Animal at "+i);
             }
        }

This code is tested
Note: Keep in mind that Don't place parent class check like in case of example code (list.get(i) instanceof Animal) at top, otherwise it will pass both cases (if checks are only if-if-if) or skip one case(and always return the object as a Animal if checks are if-else if-else if) (list.get(i) instanceof Animal) and (list.get(i) instanceof Cat) If the returning object is a Cat object.

1 Comment

What I want is an array of object type, which I can use to instantiate objects of these types. If that is possible that is.
1

As mentioned in another answer, this is not possible using purely reflection.

Unless you can customize your classes to specifically handle this case, you'd need to dive into either iterating over classes from the class loader, or using a custom class loader that adds the information into an internal data structure so that when it is requested later you don't have to reiterate over all classes.

Assuming you're not interested in diving into class loader code (it sounds like you are not), the next best way of doing this is adding static code to your classes that gets run at class loading time. For example:

public class Animal {
    protected static List subclasses = new ArrayList();
    //...
}

public class Cat extends Animal {
    static { 
        subclasses.add(Cat.class);
    }
    //...
}

This would be essentially what you would do with a custom class loader, where this code would live in the class loader instead of the class.

Repeat this pattern for all subclasses. Then when you want to create instances, you have class references inside the subclasses list, which you would instantiate with Class.newInstance (or another suitable reflection method if your constructors have arguments).

Comments

0

Since Java17, there is the concept of sealed classes, were we know all the available subclasses: Class.isSealed()

Class.getPermittedSubclasses()

https://www.baeldung.com/java-sealed-classes-interfaces

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.