Reputation: 657
I have a class A, with an abstract method doAction(BaseClass obj) expecting a param of type BaseClass
public class A {
//....
abstract void doAction(BaseClass obj);
//....
}
Now, I have another class B which needs to extend A. However, B's doAction method needs to use an object DerivedClass which extends BaseClass.
public class B extends class A {
//..
void doAction(DerivedClass obj) {
obj.callMethodAvailableOnlyInDerivedClass();
}
}
How do I handle this situation where I need to pass param of type DerivedClass to the method to be overridden while it is expecting a BaseClass ?
Thanks!
Upvotes: 16
Views: 6076
Reputation: 38132
You can use:
public abstract class A<T extends BaseClass> {
//....
abstract void doAction(T obj);
//....
}
public class B extends class A<DerivedClass> {
//..
void doAction(DerivedClass obj) {
obj.callMethodAvailableOnlyInDerivedClass();
}
}
Upvotes: 4
Reputation: 178421
There is no Contra-Variance of parameters in java, since it is not safe.
Assume you have A a = new B();
And then you invoke a.doAction(new BaseClass())
What will happen?
It will cause a run time error, since B
does not know "what to" with a BaseClass
. java wants to avoid it - so there is no covariance of parameters.
Upvotes: 1
Reputation: 691685
You make the base class generic:
public class A<T extends BaseClass> {
//....
abstract void doAction(T obj);
//....
}
and the subclass parameterized with the derived class:
public class B extends A<DerivedClass> {
//..
void doAction(DerivedClass obj) {
obj.callMethodAvailableOnlyInDerivedClass();
}
}
Without generics, it's not possible because B would break the contract of A: A accepts any kind of BaseClass, but you retrict B to only accept a specific subclass. This does not respect the Liskov principle.
Upvotes: 22