In some languages (e.g. C#) a class can only ever have 1 base class which seems like a problem for what I'm trying to do. I will give you an example of what i'm trying to do, hopefully this will make my problem clear.
I have got a lot of data objects, some of these data objects have an hierarchy, they can have a parent or a child. For these classes I created an abstract class which has 2 lists (1 of the parents and one of the children) it also has a few methods: AddChild()
, AddParent()
, RemoveChild()
, RemoveParent()
.
quick example:
Owner.AddChild(child):<br>
Adds the child to the collection of childs of 'Owner'<br>
It also adds 'Owner' to the collection of parents of 'child'.
To make sure all classes which have hierarchical components do this I created an abstract class which they all inherit so no one forgets to do it both ways.
I have also made a class for objects I want to update.
This is an abstract class not necessarily for the update part but for the equals part since I need all these classes to overwrite the Equals(object obj)
method and GetHashcode()
method and you cannot define an override in an interface (at lest not in C#)
Now clearly I'm going at this all wrong, thus my question how do I design my classes so they do get the functionality they need (and share with other classes) without creating an abstract class.
Best Answer
An interface would also "remind" developers to add those methods.
If the amount of duplicative code is small or simple, use an interface and just force inheritors to write their own implementations. In your example,
AddChild()
,AddParent()
,RemoveChild()
, andRemoveParent()
all seem pretty straightforward and simple to build.But, if the implementations are difficult for you to repeat, you could provide an "inner" class (like
TreeNode
) for inheritors to wrap:And, if that doesn't float your boat, use extension methods.
In the example from MS, a
WordCount()
method is added to theString
interface. When this namespace is included, allString
's will "automagically" have a.WordCount()
method dangling off them.I believe you can do the same sort of thing for any interface. Something like:
This would still require that the
ITreeNode
interface force inheritors to provide common properties that the extension methods can manipulate.