I have an abstract base class called WidgetBase which looks like this:
public abstract class WidgetBase : Control, INamingContainer
{
// This class declares abstract and virtual properties and methods but doesn't override anything
}
I have another abstract base class called ScrollerBase which looks like this:
public abstract class ScrollerBase : Control
{
// This class has one abstract property and overrides OnInit and OnLoad
}
I need to create a class that inherits from both of these classes. Neither class can be converted to an interface. The simplest solution that I can think of is creating an extra WidgetBase class like this:
public abstract class ScrollingWidgetBase : ScrollerBase, INamingContainer
{
// Lots of duplicated code from WidgetBase
}
It would be nice if I could do something like this:
public abstract class ScrollingWidgetBase : WidgetBase<ScrollerBase> { /* Empty */ }
public abstract class WidgetBase : WidgetBase<Control> { /* Empty */ }
public abstract class WidgetBase<T> : T, INamingContainer { /* Code goes here */ }
However this isn’t possible. The only half elegant solution that I can think of would be something like this:
public interface IScroller { /* Overridable members go here */ }
public class WidgetBase : Control, INamingContainer
{
protected override void OnInit(EventArgs e)
{
if (this is IScroller)
{
// Do scroller logic here
}
}
protected override void OnLoad(EventArgs e)
{
if (this is IScroller)
{
// Do scroller logic here
}
}
}
public class Test : WidgetBase, IScroller { }
However this would get very messy if more classes were created. Surely there must be some kind of design pattern that fixes this problem? Any help would be greatly appreciated.
Thanks,
Joe
As hyde said, you really would need to separate your behaviour from what your classes are. You said you didn’t want to use interfaces; well, I can’t think of a way around that. You may have to bite the bullet or do some code duplication.
At minimal, you can move the behaviour logic to a separate controlling class and simply feed it some interface that exposes the members needed. Consider the few properties you need for a scrollable UI control (mind you, this is all just whipped off examples, I doubt these types exist as I describe, or these are the actual minimum set needed):
You then can put your scrolling behaviour in a class that attaches that behaviour or works upon an
IScrollable:Finally, your
ScrollableWidgetwould be yourControland attach the scrolling behaviour rather than inheriting it:So yeah, you’re going to want to use interfaces. I don’t understand your requirement not to. There are other patterns, such as Decorator, that may be a better suit than the mess I just posted.