从多个类继承的解决方案
本文关键字:解决方案 继承 | 更新日期: 2023-09-27 18:15:16
所以我在一个GUI库工作,我有3个类:UIElement,每个UI对象的基础,UIContainer,它实现了容纳其他子元素的可能性和urect,它实现了元素的位置和大小。现在我想创建一个类,使用UIRect和UIContainer。显然,这样做是不可能的,但是对于这个问题有什么优雅的解决方案吗?
这里有一种可能性:继承其中一个类(例如UIRect
),并嵌入另一个类(例如UIContainer
)。实现IUIContainer
接口,但将所有调用转发给嵌入对象。
class UIRect {
...
}
interface IUIContainer {
IEnumerable<IUIElement> AllElements {get;}
void AddElement(IUIElement toAdd);
}
class UIContainer : IUIContainer {
public IEnumerable<IUIElement> AllElements {
get {
...
}
}
public void AddElement(IUIElement toAdd) {
...
}
}
class Multiple : UIRect, IUIContainer {
private readonly IUIContainer _cont = new UIContainer();
...
public IEnumerable<IUIElement> AllElements {
get {
return _cont.AllElements;
}
}
public void AddElement(IUIElement toAdd) {
_cont.AddElement(toAdd);
}
}
另一种可能性是使用两个接口,并通过扩展方法共享实现
你可以创建一个混合类,它接受UIElement, UIContainer, urect的实例作为属性,然后让你的子类实现这个混合类,并从那里获取它。
class HybridDerived : Hybrid
{
}
class Hybrid
{
public UIElement Element { get; set; }
public UIContainer Container { get; set; }
public UIRect Rect { get; set; }
}
class UIElement
{
}
class UIContainer
{
}
class UIRect
{
}
c#通常倾向于组合而不是继承,并使用接口进行通信。
的例子:
public interface IUIElement
{
}
public interface IUIContainer
{
ICollection<IUIElement> Children;
}
public interface IUIRect
{
IPosition Position { get; }
ISize Size { get; }
}
public abstract class UIElement : IUIElement
{
}
public class Multiple : UIElement, IUIContainer, IUIRect
{
private readonly ISize _size;
private readonly IPosition _position;
private readonly List<UIElement> _children = new List<UIElement>();
public Multiple()
{
}
public IPosition Position { get { return _position; } }
public ISize Size { get { return _size; }; }
public ICollection<IUIElement> Children { get { return _children; } }
}
"使用界面和组合"的一般答案似乎是多余的。可能不需要使用接口-您不太可能有一个角色,有时可以由UIRect
扮演,有时可以由UIElement
扮演,而不是UIRect
。只需在你的UIContainer中添加一个类型为UIRect的属性rect。
(在注释之后)我的回答的关键在于建议不要遵循创建接口并将调用委托给UIRect对象的私有实例的模式。
从名称上看, UIRect
具有处理屏幕上矩形空间几何形状的各种数据和逻辑。这意味着:
- 你可能不会有多个实现。欧几里得就够了;
- 你可能会发现有许多矩形描述一个UIContainer:可能是一个边界框,大小前后转换,insets等。
这只是我的判断,我没有很多数据。但是在我看来,您需要的是一个简单的组合,而不是一个描述矩形属性的附加接口。