Reputation: 30125
I am working with a Java API which requires me to implement a number of fairly large interfaces. However generally there is only one or two details that actually vary between implementations, so I made some abstract base classes to provide most of the implementation.
However now Ive come across cases where I need to extend from some other class and/or implement multiple such interfaces, and so I am unable to extend my abstract base classes.
In C++ I was able to use multiple inheritance, and also use some other tricks like below. However Java doesn't allow multiple inheritance, or generics to be used in this way.
class MyClass : public HelperForInterfaceA, public HelperForInterfaceB {...};
class template<class BASE> MyHelper : public BASE {...};
The best idea I have right now is to have the concrete implementation of my abstract helper class as a field, and then make all the interface methods forward to that field instance, with the field having a reference to the main object to implement the last details if needed.
class MyClass extends A implements IB, IC {
private static class B extends BAbstractHelper {
private A a;
public B(A a, int size) {
super(size);
this.a = a;
}
@Override
public boolean foo(int x, int y) {
return a.foo(x, y);
}
}
private static class C extends CAbstractHelper {
...
}
private B b;
private C c;
private int range;
@Override
public boolean foo(int x, int y) {
return x*x + y*y <= range*range;
}
@Override
public float bar(float x, int y, String s) {
return b.bar(x,y,s);
}
...
}
However this seems a bit of a pain, with a lot of wrapper methods required. Is there a better way of dealing with this?
Upvotes: 5
Views: 421
Reputation: 2376
A Java best practice is to prefer composition over inheritance. Keeps things simpler but creates more boilerplate code. You have the right idea to create delegate methods. A good Java IDE can generate all the boilerplate delegate methods code for you. Other languages on the JVM like Scala (with traits) make this easier.
Upvotes: 1