Gabriele Gabriele - 3 months ago 30
Java Question

Specializing method arguments in subclasses in Java

Consider the following situation:

public abstract class AnimalFeed{
public class FishFeed extends AnimalFeed{
public class BirdFeed extends AnimalFeed{

public abstract class Animal{

public void eat(AnimalFeed somethingToEat)


Now I would like to define a class "Bird" extending "Animal" being sure that when the bird eats, it eats only BirdFeed.

One solution would be to specify a sort of contract, in which the caller of "eat" must pass an instance of the appropriate feed

public class Bird extends Animal{

public void eat(AnimalFeed somethingToEat){

BirdFeed somethingGoodForABird

somethingGoodForABird = (BirdFeed) somethingGoodForABird
//throws error, complaining the caller didn't feed the bird properly

Is it acceptable to delegate the responsibility of the parameter to the caller? How to force the caller to pass a specialization of the parameter? Are there alternative design solutions?


You'd need to add a type variable to the class:

public abstract class Animal<F extends AnimalFeed> {
  public abstract void eat(F somethingToEat);

Then you can declare your subclasses as wanting a particular type of AnimalFeed:

public class Bird extends Animal<BirdFeed> {
  public void eat(BirdFeed somethingToEat) {}

public class Fish extends Animal<FishFeed> {
  public void eat(FishFeed somethingToEat) {}