Search code examples
javagenericsinheritancerestriction

Java generics - restrict child class object stored in parent class argument


I have classes Parent and (Child extends Parent). Also I have classes A and (B extends A).

Have the following code setup:

class Parent {
  method (A a) {
    //some actions
  }
}

class Child extends Parent {
 method (B b) {
   super.method(b)
   // some additional actions
 }
}

Let's say we have the following:

Parent p = new Parent();
Child c = new Child();
A a = new A();
B b = new B();

The requirement is the following:

p.method(a); // success
p.method(b); //RunTimeException

c.method(a); //RunTimeException
c.method(b); //success

The primary problem here is c.method(a) and p.method(b) works successfully.

Is it possible to achieve this behavior using generics? Any suggestion is appreciated.

Thanks.


Solution

  • You can always throw RuntimeExceptions as you wish, but you should not, you most likely want to have a compiler error instead!? And then the question is: why? A Child is a Parent, and everything you can call on the parent should also work on the child, see the L in SOLID.

    You might be able to achieve this with generics by using a

    class Parent<T> { 
        void method (T t) { ... }
    }
    
    class Child<T> extends Parent<T> {
        void somethingElse () { ... }
    }
    

    and then

    Parent<A> p = new Parent<>();
    Child<B> c = new Child<>();
    A a = new A();
    B b = new B();
    
    p.method(a); // works
    p.method(b); // compiler error
    
    c.method(a); // compiler error
    c.method(b); // works
    

    But at that point the Child<B> is something completely different compared to the Parent<A> and the Parent p = c; that would have worked previously is no longer valid / available.