我有一个关于如何在我的C#程序中以正确的方式使用接口和抽象类的问题。我有许多独立的“模块”(BeatsPerMinuteMeasurement,MouseRecorder,ClipboardHistory等)。所有这些都至少有一个Panel(UserControl)和一个“Logic”(普通类)。首先,没有继承权。但现在我正在重写它:( - >)意味着继承自:
问题:这是一个很好的方法吗?这是我的面板代码(因为奇怪的继承错误而无法正常工作):
interface IBasePanel {
void RegisterEvents();
void Close();
}
abstract class BasePanel : UserControl, IBasePanel {
public BasePanel() {
InitializeComponent();
RegisterEvents(); //Compiler error, compiler cant find it
}
public abstract void InitializeComponent();
}
class MouseKeyRecord_Panel : BasePanel {
//GUI variables (buttons/labels etc.)
public MouseKeyRecord_Panel() {
}
protected override void RegisterEvents() {
//Register EventHandler for buttons etc.
}
protected override void InitializeComponent() {
//Visual Studio auto generated GUI
}
public override void Close() {
//Closing Threads etc.
}
}
修改1 解决了。 我删除了界面,现在正在运行。我想我用错误的方式使用了接口。我仍然不知道何时使用抽象类以及何时使用接口。
答案 0 :(得分:0)
发生编译器错误是因为,正如编译器所述,RegisterEvents()
和Close()
所需的实现没有出现在BaseClass
实现中。
如果要将实现推迟到子类,那么在基类中实现接口的正确方法是声明abstract
实现,就像您对InitializeComponent()
所做的那样:
abstract class BasePanel : UserControl, IBasePanel {
public BasePanel() {
InitializeComponent();
RegisterEvents();
}
public abstract void InitializeComponent();
public abstract void RegisterEvents();
public abstract void Close();
}
那就是说,请注意,简单地进行上述更改将无法获得您发布的代码进行编译。必须使用public
成员实现隐式实现的接口。您无法RegisterEvents()
成为protected
成员。另一方面,如果您确实希望它是protected
成员,那么它可能不应该在接口中,因为接口的设计成员应该是公共的。
同样,您在InitializeComponent()
方法中遇到问题,您已在基类中声明为public
,但在派生的MouseKeyRecord_Panel
类中为protected
。您无法更改虚拟成员覆盖的可访问性。将覆盖设置为public
方法,或将基类声明更改为protected
。
您可能还不知道何时使用抽象类和接口。但第一步是了解如何。 :)对于"当"时,简短的回答是抽象类和接口非常相似;主要的例外是抽象类除了声明的接口之外(并且通常会)包括一些实际的实现(即抽象类的abstract
成员实际上是该类声明的接口...请注意,与接口不同,abstract
抽象类的成员不必是public
)。
此外,当然是一个实际的类,任何给定的类型最多只能继承一个抽象类(如果它已经继承了其他类,则没有)。您可以实现任意数量的接口(有些人将其描述为继承接口,但我倾向于考虑继承实现和实现接口)。
任何比这更深入的解释是恕我直言,Stack Overflow太广泛了,最好留给网上的教科书,博客和其他文章中的许多资源(包括MSDN上的C#文档)。