Array中抽象类的派生类

New*_*ger 2 c# arrays abstract-class derived-class

今天是个好日子.

我有一个关于制作和使用某些基本抽象类的派生类的问题.

我不太明白它是如何工作的.

我的目标:创建一个基本类,定义应该有哪些函数,然后创建不同的派生类.然后创建一个基类数组并在其中实例化不同的派生类.

例如:

abstract class UIElement
{
    //constructor
    abstract public UIElement();
    //draw element
    abstract public void Draw(int mouseX, int mouseY);
    //checks if the element is pointed at by mouse
    abstract public Boolean IsPointed(int mouseX, int mouseY);
    //defines what happens when clicked
    abstract public void Click(int mouseX, int mouseY);
    //destructor
    abstract public ~UIElement();
}
Run Code Online (Sandbox Code Playgroud)

然后创建几个派生类,并执行以下操作:

UIElement[] qwe = new UIElement[3];
qwe[0] = new UIElementButton();
qwe[1] = new UIElementLabel();
qwe[2] = new UIElementSomethingElse();
Run Code Online (Sandbox Code Playgroud)

1)这样做的正确方法是什么,因为我无法找到明确的答案或一篇可以解释它的文章......

2)关于类变量,应该声明它们:基类还是派生?

3)如果不同的派生类有不同的变量,应该如何解决该怎么办?

4)派生类可以有不同的构造函数,包括不同的参数吗?

Dr.*_*ABT 6

在下面的评论中,提问者正在寻找有关使用抽象类编写继承层次结构的最佳实践的建议

从一般的最佳实践和正确的角度来看,你应该在构造函数中没有抽象而没有终结器的情况下声明你的UIElement基类.例如

public abstract class UIElement
{
    //constructor
    protected UIElement();
    //draw element
    public abstract void Draw(int mouseX, int mouseY);
    //checks if the element is pointed at by mouse
    public abstract bool IsPointed(int mouseX, int mouseY);
    //defines what happens when clicked
    public abstract void Click(int mouseX, int mouseY);
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以按如下方式实现派生类

public class UIElementButton : UIElement
{
    // Optional - create parameterless constructor and
    // explicitly call base constructor
    public UIElementButton() : base()
    {
    } 

    // Mandatory - must override abstract methods
    public override Draw(int mouseX, int mouseY)
    {
    }

    // Mandatory - must override abstract methods
    public override Boolean IsPointed(int mouseX, int mouseY)
    {
    }

    // Mandatory - must override abstract methods
    public override void Click(int mouseX, int mouseY)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

您是正确的,如果您按照上面的定义派生类,您可以实例化元素并存储在基类型的数组中,如下所示:

UIElement[] qwe = new UIElement[3]; 
qwe[0] = new UIElementButton(); 
qwe[1] = new UIElementLabel(); 
qwe[2] = new UIElementSomethingElse(); 

qwe[0].Click(1, 2); // Invokes UIElementButton.Click
qwe[1].Draw(3, 4);  // Invokes UIElementLabel.Draw
Run Code Online (Sandbox Code Playgroud)

您还应该知道WPF中定义了一个UIElement类.如果为类型定义命名空间,这可能不是问题,但可能会考虑更明确的类型名称,BaseElement以区分您的自定义类型.


关于您在评论中的查询:

有关抽象类使用的进一步建议,请参阅所有关于抽象类 - Codeproject. - 应该在哪里声明类变量:基类还是派生? - 如果不同的派生类有不同的变量,应该如何解决? - 派生类可以有不同的构造函数,包括不同的参数吗?

这些确实是关于谷歌的不同问题或自己研究的主题,但作为首发,我可以说:

  1. 类变量应在需要它们的范围内声明.这意味着如果您有一个变量Guid _uiElementId并希望它被派生类型访问,那么它应该在基类中声明并标记为protected.如果在UIElementButton中有一个变量,Point _mousePoint并且只有UIElement按钮需要它,请将其保留在那里并标记为private

  2. 没关系 - 任何类型都可以从基类中看到自己的私有变量和受保护的变量.只要确保名称不会发生冲突

  3. 是的,他们可以,例如.


 public class UIElementButton : UIElement    
 {    
    private string _buttonText; 

    // Overloaded ctor
    public UIElementButton(string buttonText) : base()
    {
        buttonText = buttonText;
    } 

    // Default constructor. Mark as private or protected 
    // to hide from external API
    public UIElementButton() : base()
    {
    } 
}
Run Code Online (Sandbox Code Playgroud)

最好的祝福,