'Seeing no way to avoid (deeper) inheritance tree without producing code duplication
I am rather new to OOP and I can't wrap my head around a problem I have frequently encountered by now. I hope, I understand the reasoning behind why composition is favorable to inheritance (the deeper the inheritance tree the more coupling you have and the more likely maintenance difficulties will arise in later stages). But at the same time I see no way how to avoid code duplication without making use of abstract (template) classes. So this is the specific situation I am having difficulties with at the moment (if the description is too confusing there's an UML class diagram attached in the link below...I cant upload pictures directly unfortunately, as you need 10 reputation points for that):
I have an interface i1 with the methods m1, m2, m3.
It is absolutely clear that every class implementing this interface (by now there are 3 concrete classes C1, C2, C3) will have the attributes a1, a2 and a3. All these will be set in the constructor of the specific class in the same manner. Also the methods m1, m2 and m3 are implemented in the same fashion across all classes, because they delegate the method calls to one of the class attributes (a1).
Already here I cant wrap my head around how I can reasonably do without inheritance. Would it be the better solution to duplicate the constructor code across all the concrete classes c1, c2 and c3? And to implement the delegation in the methods m1, m2 and m3 every time in each new concrete class?
But it doesnt stop here. c2 and c3 do need more functionalities than given in interface i1. So there is another interface i2 with the methods m4,m5. Again both these methods will be delegated in the same manner to a1. So c2 and c3 are absolutely identical as of now. However they cant be the same class, because c3 once again needs more functionality so it implements an interface i3 with the methods (m6,m7). So if I dont use inheritance the classes c2 and c3 will have 5 methods which will be duplicated, but if used inheritance for the whole design, I will already have reached a somehwat deeper inheritance level, because there will be an abstract class for the classes c1, c2 and c3 (where the constructor code will be implemented and the methods m1,m2 and m3) and one abstract class for the classes c2 and c3 where the methods m4 and m5 will be implemented.
I found some languages have things called mixins or traits. The language I am working in (ABAP) doesnt have these. But maybe I still have some fundamental problem in my understanding.
Any help is very appreciated. Thank you!
Solution 1:[1]
The description is a bit confusing so correct me if I've got it wrong.
It seems like you have a single implementation of each one of the interfaces. Simply compose this implementation in every class that you want to have this functionality. For example, C1 will compose the implementation of i1 and C2 will compose the implementation of i1 and i2. The implementation itself will, of course, gets in the ctor the same parameters.
If for convenience you wish to treat, for example, C1 as an implementation of i1, you may do it with a user-defined conversion function:
operator i1&() { return m_i1; }
Where m_i1 is the composited implementation of i1.
This way the inheritance is of depth 1. Moreover it's can be easily extended and changed. For example, maybe C1 would like a different implementation of i1 then C2 it will be easily achieved.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ODgn |
