nervosol
nervosol

Reputation: 1291

Class object as List's type

I have class Animal and two subclasses Tiger and Eagle. Both of subclasses have hunt method which is pretty much the same. The only difference between them is type of Victims. Method hunt is using generic class Field<T> for seekeing victims. It looks like this:

Tiger

void hunt(){
  Field<Cattle> field = new Field<Cattle>();
  List<Cattle> list = field.getObjects();
  ...

Eagle

void hunt(){
  Field<Rabbit> field = new Field<Rabbit>();
  List<Rabbit> list = field.getObjects();
  ...

Is there any way to perform something like that?

void hunt(Object type){
  Field<type> field = new Field<type>();
  List<type> list = field.getObjects();

I know that I can get list full of Object type and use instanceof later, but here we come to second question:

Is it possible to call if( object instanceof instanceOfSomeClass)?

Upvotes: 1

Views: 82

Answers (3)

Roberto
Roberto

Reputation: 9080

If I understood correctly, you can use a generic method using following code:

If you pass the object class, not the instance, you can construct a Field instance using the Class passed as parameter.

public class MyAnimal {
    public <T> void hunt(Class<T> type) {
        Field<T> field = new Field<>();
        List<T> list = field.getObjects();

        if (type == Cattle.class) {
            System.out.println("Type is a Cattle");
        } else {
            System.out.println("Type is not a Cattle, is a " + type.getName());
        }
    }

    public static void main(String[] args) {
        new MyAnimal().hunt(Cattle.class);
        new MyAnimal().hunt(new Cattle().getClass());
    }
}

About your second question, if you have the Class type, you can ask with a simple: type == MyClass.class.

Upvotes: 1

Guillermo Merino
Guillermo Merino

Reputation: 3257

You can use generics to achieve what you want:

public class AnimalsGenerics<E> {
    public void Hunt(E prey){
       ...
    }
}

and implement your animals specifying the prey:

public class Tiger extends AnimalsGenerics<Buffalo> {
}

But my personal implementation would be using interfaces to specify what does the animal do, for example: what happens if the animal is not a hunter, for example an herbivorous, would you need to implement your animal class again? follow the principle of leaving the implementation to the interfaces and not the heritance would help you to have a cleaner code, my dessign would be:

To design the behaviour:

public interface CollectFoodBehaviour<E> {
    void collectFood(E prey);
}

Class animal would be:

public class Animal<E> {

    CollectFoodBehaviour<E> collectFoodBehaviour;

    public  void goToGetFood(E food){
        collectFoodBehaviour.collectFood(food);
    }
}

Implementing the hunting behaviour:

  public class HuntAnimalsBehaviour<E> implements CollectFoodBehaviour<E> {
        @Override
        public void collectFood(E prey) {
            //implemenet the generic hunting process
        }
    }

and an animal instance as an example:

public class Dog extends Animal<Rabbit> {

    public Dog(){
        this.collectFoodBehaviour = new HuntAnimalsBehaviour<Rabbit>();
    }
}

Upvotes: 2

user1803551
user1803551

Reputation: 13407

Is it possible to call if( object instanceof instanceOfSomeClass)?

No, instanceof tests if an object is an instance of a class, not an instance of an instance (as if the left side is a non-static reference and the right side is static reference); You can, however, not declare your instance

// JButton b = new JButton();
// if (b instanceof Component) can be replced with
if (JButton.class.newInstance() instanceof Component)
// or
if (new JButton() instanceof Component)

if for some odd reason you find this useful.

Upvotes: 1

Related Questions