从多个类继承的解决方法?

时间:2013-05-24 14:03:16

标签: c# class inheritance

所以我正在开发一个GUI库,我有3个类:UIElement,每个UI对象的基础,UIContainer,它实现了保存其他子元素的可能性,UIRect实现了元素的位置和大小。现在我想创建一个同时使用UIRect和UIContainer的类。显然这是不可能的,但这个问题有没有优雅的解决方案?

4 个答案:

答案 0 :(得分:4)

这是一种可能性:继承其中一个类(比如UIRect),然后嵌入另一个类(比如UIContainer)。实现IUIContainer bu的接口转发所有对嵌入对象的调用。

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);
    }
}

另一种可能性是使用两个接口,并通过扩展方法共享实现。

答案 1 :(得分:3)

您可以创建一个混合类,它接受UIElement,UIContainer,UIRect的实例作为属性,然后让您的子类实现混合并从那里获取它。

 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 
 {
 }

答案 2 :(得分:2)

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; } }
}

答案 3 :(得分:1)

“使用界面和构图”的通用答案似乎有些过分。可能不需要使用界面 - 您可能不会有UIRect有时可以播放的角色,有时候UIElement可能不是UIRect。只需将UIRect类型的属性rect添加到您的UIContainer。

<强>更新

(评论之后)我的答案的关键在于建议不要遵循创建接口的模式并将调用委托给UIRect对象的私有实例。

从名称来看,

UIRect具有处理屏幕上矩形空间几何的各种数据和逻辑。这意味着:

  • 您可能没有多个实现。欧几里德就足够了;
  • 您可能会发现有许多描述UIContainer的矩形:可能是边界框,转换前后的大小,插图等。

这只是我的判断,我没有太多数据。但是从我看来,你需要一个普通的合成,而不是一个描述矩形属性的附加接口。