c# - 数组中抽象类的派生类

标签 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();
}

然后创建几个派生类并这样做:

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

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

2)关于类变量,应该在哪里声明:基类还是派生?

3) 如果不同的派生类有不同的变量怎么办?

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

最佳答案

In comments below, questionner is looking for advice on best practices for writing inheritence hierachies with abstract classes

从一般的最佳实践和正确性的角度来看,您应该声明 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);
}

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

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

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

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

您还应该知道 WPF 中定义了一个 UIElement 类。如果您为您的类型定义命名空间,这将不是问题,但也许考虑使用更明确的类型名称(如 BaseElement)来区分您的自定义类型。


关于您在评论中的查询:

有关使用抽象类的更多建议,请参阅 All about abstract classes - Codeproject . - 应该在哪里声明类变量:基类还是派生类? - 如果不同的派生类有不同的变量怎么办,应该如何解决? - 派生类可以有包含不同参数的不同构造函数吗?

这些确实是不同问题或自己在 google 上进行研究的主题,但是作为初学者,我可以说:

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

  2. 没关系 - 任何类型都可以看到自己的私有(private)变量和来自基类的 protected 变量。只要确保名称不冲突

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

最好的问候,

关于c# - 数组中抽象类的派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8969563/

相关文章:

c# - 找出给定长度的所有可能单词的好方法是什么

c++ - 使用指针作为参数在数组中查找 char 的索引

Java封装的Array mutator方法

C++在尝试覆盖方法时无法实例化抽象类

c# - 流利的 NHibernate : Cascade delete from one side only on Many-to-Many relationship

javascript - 在javascript中返回带参数的消息

c# - 方法不会正确地将值分配给 selectindex,asp.net radiobuttonlist

c++ - 在 C++ 中将对象序列化为字节数组

java - 抽象类和方法|意见含糊不清

scala - 类是抽象的;无法在凿子上实例化错误