0

I have two classes, let's call them Foo and Bar. They both extend different classes (Foo extends X, Bar extends Y), which have some common ancestor "way up" the inheritance tree, something like this:

enter image description here

Both Foo and Bar have some common class members (and some more members which they don't share), and I would like to implement a method which will be the same for both classes, acting on these members. The catch is - I cannot change the inheritance tree and add a superclass which will be the same for both (while this might be a sign for a bad design of the classes and inheritance, this is not what I ask here).

For simplicity, let's assume that the similar class members will be member1 and member2, and the relevant function name will be func().

One option I thought of, is to encapsulate the similar class members in a new class, and create the relevant method for it. For example, I can create a class named Baz which will hold both member1 and member2, and Foo and Bar will contain the Baz class instead of these members. The methods func() in both Foo and Bar will just call the baz.func().

This is one indeed solution. However, what should be a solution where I can't change the class members as well? In that case, I thought of making both Foo and Bar implement an interface (for simplicity, let's call it IFunc). And create a method (either static or not) somewhere else which will have an IFunc argument which will mimic func. But this seems like a not so good solution. What will be a better solution for this case?

To clarify: I am trying to eliminate code duplication in the implementation of func

Thanks!

  • 1
    Are you trying to eliminate code duplication in the implementation of these two or in code using these two? I thought it was the latter at first, but sounds more like the former. If former then with such implementation details, and in Java, I'd favor encapsulation over the static method if you can (but I'd think about the encapsulated class's design and not make it some willy-nilly "helper"). – Dragon Energy Dec 13 '18 at 10:13
  • 1
    See this quesztion on SO: stackoverflow.com/questions/269496/inheritance-vs-aggregation, there are some good answers. – helb Dec 13 '18 at 10:15
  • @DragonEnergy thanks for the reply, I indeed meant the former (i.e eliminating code duplication in the implementation of func). I will clarify it in the question – Mickey Dec 13 '18 at 10:16
2

Ok, I'm assuming here that you cannot in fact change the super classes of Foo or Bar in my answer.

Logically, Foo and Bar derive from their respective X and Y classes for a reason. Foo is a type of X and not a type of Y and vice versa. Respect that and don't try to force a Foo and Bar into a weird hybrid class deriving from a distant ancestor. If the relationship between Foo and Bar doesn't mirror inheritance as is, then create a new inheritance tree which does.

In situations like this, generally you'd use an Adapter pattern. The idea is you create a new abstract class representing this new relationship representing these things in common. Then your concrete classes extend this abstract class which does little more than encapsulate Foo or Bar and provides consistent behavior between the two.

When you need to use it, you need only deal with the abstract class which unifies behavior between the two. The downside being of course that you can't use this adapter where you'd normally be able to use Foo or Bar, but then if I understand correctly, neither one can be used interchangeably as is anyway. You'd be getting all the flexibility you require without the awkwardness of trying to make a sphere fit into a square hole.

Hope that helps!

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.