В комментариях ниже вопросник ищет советы по передовой практике написания иерархий наследования с абстрактными классами
С точки зрения общей передовой практики и правильности вы должны заявитьваш базовый класс 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
, чтобы отличить ваш пользовательский тип.
По поводу ваших запросов в комментариях:
Дополнительные советы по использованию абстрактных классов см. Все об абстрактных классах - Codeproject ,- Где должны быть объявлены переменные класса: базовый класс или производный?- Что, если разные производные классы имеют разные переменные, как это следует учитывать?- Могут ли производные классы иметь разные конструкторы, включая разные аргументы?
Это действительно тема для различных вопросов или собственного исследования в Google, однако в качестве начала я могу сказать:
Переменные класса должны быть объявлены в области, где онинеобходимы.Это означает, что если у вас есть переменная Guid _uiElementId
и вы хотите, чтобы к ней обращались производные типы, она должна быть объявлена в базовом классе и помечена как protected
.Если у вас есть переменная в UIElementButton с именем Point _mousePoint
, и она нужна только кнопке UIElement, оставьте ее там и отметьте как private
Это нормально - любой тип может видеть свой собственныйпеременные и защищенные переменные из базовых классов.Просто убедитесь, что имена не конфликтуют
Да, они могут, например.
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()
{
}
}
С уважением,