从多个类继承的解决方案

本文关键字:解决方案 继承 | 更新日期: 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等。

这只是我的判断,我没有很多数据。但是在我看来,您需要的是一个简单的组合,而不是一个描述矩形属性的附加接口。