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:
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 Answer 1
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!
Explore related questions
See similar questions with these tags.
func
). I will clarify it in the question