I have several Java interfaces/ABCs/classes:
public abstract class Target {
public abstract void fire(Load load);
}
public class HttpTarget extends Target {
@Override
public void fire(Load load) {
// ...
}
}
public interface Load {
// ...
}
public class HttpLoad implements Load {
// ...
}
// Inside a driver
Target target = testSuite.getTarget();
Load load = testSuite.getLoad();
target.fire(load);
So essentially a Target can fire() a Load. My main app Driver doesn’t care about what kind of Target is returned by getTarget(), or what kind of Load is returned by getLoad(). It’s job is to make sure that a load is fired.
I’d like to change the fire() method definition inside HttpTarget to:
@Override
public void fire(HttpLoad httpLoad) {
// ...
}
However when I do that, Java complains that the method override doesn’t match the definition provided by its parent Target class (as Load and HttpLoad are two different things).
What’s the solution here? Generics? Abstract factories? Ultimately, I want to be able to enforce that HttpTarget‘s fire() method can only accept HttpLoads, but still be compatible with the Driver code. Can someone provide a code example? Thanks in advance!
Yes, you would need generics:
The reason Java refuses to compile your HttpTarget class is because it doesn’t override the Target’s
fire(Load)method. Indeed, a Target, by contract is supposed to accept any kind of Load as argument. And theHttpTarget‘sfire()method only accepts instances of HttpLoad, and thus breaks the Liskov principle. Generics are the solution to this problem.