I'm having issues enforcing an (Enum) interface implementation as an overridden method parameter in Java. Relevant (simplified) code that shows what I'm trying to do:
public interface AnimalSound {}
public enum CowSound implements AnimalSound {
MOO, BOO
}
public interface Animal {
<T extends AnimalSound> T getSound();
<T extends AnimalSound> void setSound(T sound);
}
public class Cow implements Animal {
@Override
public CowSound getSound() {
return CowSound.BOO;
}
@Override
public <T extends AnimalSound> void setSound(T sound) {
if(sound.getClass() != CowSound.class) throw new IllegalArgumentException("Only works with cow sounds!");
}
}
The #getSound works just fine (when I suppress the IDE Unchecked overriding warning). The #setSound however doesn't enforce a CowSound here, and I'd rather the IDE/compiler enforces this than throwing an exception during runtime.
What I -want- to do with the #setSound method is something like:
@Override
public void setSound(CowSound sound) {//set a sound}
This however doesn't override the interface. Is there a better/other way to enforce the CowSound implementation here instead of accepting any implementation of AnimalSound and throw a runtime exception?
The problem is that you're making the individual methods generic, while you need to make the type generic. So, you need to use:
public interface Animal<T extends AnimalSound> {
T getSound();
void setSound(T sound);
}
and
public class Cow implements Animal<CowSound> {
@Override
public CowSound getSound() {
return CowSound.BOO;
}
@Override
public void setSound(CowSound sound) {
// ...
}
}