I've run into a bit of a problem with my class hierarchy, in a WPF application. It's one of those issues where you have two inheritance trees merging together, and you can't find any logical way to make your inheritance work smoothly without multiple inheritance. I'm wondering if anyone has any bright ideas for getting this kind of system working, without making it impossible to follow or debug.
I'm a low-level engineer, so my first thought is always, "Oh! I'll just write some of these classes in native C++, and reference them externally! Then I can have all my old-school OO fun!" Alas, this doesn't help when you need to inherit from managed controls...
Allow me to show a snippet of my current projected class diagram:
____________________________________ _____________________________________ | CustomizableObject | | System.Windows.Controls.UserControl | |____________________________________| |_____________________________________| | string XAMLHeader() | ▲ | string XAMLFooter() |◄--┐ | | CustomizableObject LoadObject() | \ | | <Possible other implementations> | \ | |____________________________________| \ | ▲ ▲ \ | | | \ | | | \ | _________________ ______________________ \ _____________________ | SpriteAnimation | | SpriteAnimationFrame | └---| CustomizableControl | |_________________| |______________________| |_____________________| ▲ ▲ | | | | ________ _____________ | Sprite | | SpriteFrame | |________| |_____________|
The problem is pretty clear: the separation of the CustomizableObject and CustomizableControl object trees --- and the insertion of UserControl into one, but not both, of the trees.
It makes no practical sense to move the implementation of CustomizableObject into its derived classes, since the implementation doesn't vary by class. Furthermore, it would be really confusing to have it implemented multiple times. So I really don't want to make CustomizableObject an interface. The interface solution doesn't make any sense to me. (Interfaces have never really made much sense to me, to be honest...)
So I say again, anyone have any bright ideas? This one's a real pickle. I'd like to learn more about making interfaces work WITH my object tree, rather than against it. I'm making this simple sprite engine using WPF and C# as a solid exercise, more than anything. This is so easy to solve in C++ - but I need to figure out how to solve these problems in a managed environment, rather than throwing my hands in the air and running back to Win32 whenever the going gets tough.
Automating delegation, in combination with a multiple subtyping mechanism, provides many of the same benefits as multiple inheritance, yet sidesteps most of the associated problems. Automated delegation could satisfy both the designers and the users of class based object oriented languages.
Delegation can be an alternative to inheritance. Delegation means that you use an object of another class as an instance variable, and forward messages to the instance.
NET and Java designers did not allow multiple inheritance because they reasoned that adding MI added too much complexity to the languages while providing too little benefit.
You have two options here; use interfaces, or use composition. Honestly, interfaces are very powerful, and after reading this line
The interface solution doesn't make any sense to me. (Interfaces have never really made much sense to me, to be honest...)
I think that you should learn how to use them properly. That said, if there is simply some logic that multiple class need, but it does not make sense for these classes to inherit from the same base class, just create a class to encapsulate that logic and add a member variable of that class to your classes that are giving you problems. This way all of the classes contain the logic but can be separate in their inheritance hierarchies. If the classes should implement a common interface(s), then use interfaces.
One approach is to use extension methods with an interface to provide your "derived class" implementation, much like System.Linq.Queryable:
interface ICustomizableObject { string SomeProperty { get; } } public static class CustomizableObject { public static string GetXamlHeader(this ICustomizableObject obj) { return DoSomethingWith(obj.SomeProperty); } // etc } public class CustomizableControl : System.Windows.Controls.UserControl, ICustomizableObject { public string SomeProperty { get { return "Whatever"; } } }
Usage: As long as you have a using directive for (or are in the same namespace as) the namespace where your extension methods are defined:
var cc = new CustomizableControl(); var header = cc.GetXamlHeader();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With