Diff Think
Diff Think

Reputation: 21

OOP and DI in Java

There is some base class BaseA with lazy injected field foo (or not lazy).

public class BaseA {
  @Inject
  protected Provider<BaseY> foo;

  void someMethod1(){
   BaseY bar = foo.get();
   //...using "bar"
 }
}

Class BaseY was extended by class DerivedY:

public class DerivedY extends BaseY{
}

The base class BaseA was extended by class DerivedA. How can I use DerivedY instance in DerivedA class?

1st variant:

public class DerivedA extends BaseA {
  @Inject
  protected Provider<DerivedY> foo;

  void someMethod2(){
    DerivedY bar = foo.get();
    //...using "bar"
  }
}

But in this case FindBugs, for example, throws next violation "Class defines field that masks a superclass field (MF_CLASS_MASKS_FIELD)".

2nd variant:

public class DerivedA extends BaseA {
  void someMethod2(){
    DerivedY bar = (DerivedY)foo.get();
    //...using "bar"
  }
}

2nd variant requries using downcasting which is a violation of the Liskov substitution principle.

Which solution is right in this case (best practies)? What literature (or links) can you advise on this question?

Upvotes: 2

Views: 266

Answers (2)

Kaneda
Kaneda

Reputation: 721

Use the BaseY just doens't resolve? Since DerivedY is the only subclass, will be used as @Default by the CDI. in BaseY you will get a DerivedY.

Upvotes: 0

jaco0646
jaco0646

Reputation: 17164

I advise researching generics. One solution to this problem could be a generic base class.

public class BaseA<T extends BaseY> {
    final Supplier<T> foo;

    public BaseA(Supplier<T> foo) {
        this.foo = foo;
    }
}

public class DerivedA extends BaseA<DerivedY> {
    public DerivedA(Supplier<DerivedY> foo) {
        super(foo);
    }
}

Upvotes: 1

Related Questions