windsor
windsor

Reputation: 183

Avoid instanceof but restrict function parameter to a set of subclasses of a superclass

In other words how to force a method to only use subclasses of the given input parameter which is a superclass?

Example:

public class Animal {
    ...
}

public class Dog extends Animal {
...
}

public class Cat extends Animal {
...
}

public class Test {
   ...
   public void makeSound(Animal animal) throws Exception{
      if(animal instanceof Dog){
         System.out.println("bark");
      } else if (animal instanceof Cat) {
        System.out.println("meow");
      } else {
        throw new Exception ("Not valid subclass of Animal");
      }
   }
}

The code above seems somehow wrong, is there a better, more efficient or generic way?

Upvotes: 0

Views: 227

Answers (1)

Rohit Jain
Rohit Jain

Reputation: 213243

To avoid doing the instanceof check for each subtype, you can create an abstract makeSound() method in Animal class, and override in all the subclasses. I would make the Animal class abstract, as it really is an abstract entity in your scenario:

abstract class Animal {
    abstract void makeSound();
}

class Dog extends Animal {
    void makeSound() { System.out.println("Bark"); }
}

class Cat extends Animal {
    void makeSound() { System.out.println("Meow"); }
}

and then in Test class, just invoke makeSound on Animal reference. It will call appropriate overridden method based on actual instance:

public void makeSound(Animal animal){
    animal.makeSound();
}

Now, everytime you add a new subtype of Animal, you just need to override makeSound() in that class. With abstract method, you will be forced to do that. And keep the Test#makeSound() method unmodified.

Upvotes: 1

Related Questions