16

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!

Skynet
  • 657
  • 2
  • 9
  • 25

3 Answers3

22

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.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
4

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();
  }

}
Puce
  • 37,247
  • 13
  • 80
  • 152
1

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.

amit
  • 175,853
  • 27
  • 231
  • 333