Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforce subclass Java type on parameter [duplicate]

Is there any way of enforcing the subclass type on a parameter at compilation time?

Something like this but not for instances - for classes?

I have the classes:

public abstract class Animal {

  public abstract void follow(Animal a); // <-- how to declare it?

}

but I would like a subclass to never use the Animal base class, but rather only itself (the deriving class) as parameter:

public class Fish extends Animal {

  @Override
  public void follow(Fish f) { // error here, since it expects Animal
    tagAlong(f);
  }

  private void tagAlong(Fish f) {
    // do something  
  }

}

I want a Fish to only use parameters of type Fish, not Animal, the same way another subclass Parrot would use only a Parrot parameter on the method follow().

I would strongly prefer to enforce this at compilation time, but if nothing else is possible runtime is a (less desirable) option.

like image 449
The Impaler Avatar asked Nov 14 '25 23:11

The Impaler


1 Answers

There is a trick to this.

From a design perspective, it's ugly, but it'll work in your case.

First things first: note that there's nothing really wrong with parametrizing with Animal, and checking the type at runtime.

Here's how to enforce inheritance with same-type parameter as method's signature:

// made class generic
public abstract class Animal<T extends Animal<T>> {

    public abstract void follow(T a);

}

// parametrizes with own type
public class Fish extends Animal<Fish> {

    @Override
    public void follow(Fish a) {
        // compiles
    }

}

You could also declare a generic method follow instead, parametrized with <T extends Animal> (and just T in the signature), but you can't enforce Fish in the signature in the Fish class.

like image 84
Mena Avatar answered Nov 17 '25 18:11

Mena



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!