C# 将接口和基类用于独立;“模块”;

C# 将接口和基类用于独立;“模块”;,c#,interface,module,subclass,abstract,C#,Interface,Module,Subclass,Abstract,我有一个关于如何在我的C#程序中正确使用接口和抽象类的问题。我有许多独立的“模块”(BeatserMinuteMeasurement、鼠标记录仪、剪贴簿历史记录等)。它们都至少有一个面板(UserControl)和一个“Logic”(普通类)。首先,没有继承权。但现在我将其改写如下:(>)表示继承自: SomeLogic->BaseLogic->IBaseLogic SomePanel->BasePanel->UserControl,IBasePanel 问题是:这是一个好方法吗?这是我的面

我有一个关于如何在我的C#程序中正确使用接口和抽象类的问题。我有许多独立的“模块”(BeatserMinuteMeasurement、鼠标记录仪、剪贴簿历史记录等)。它们都至少有一个面板(UserControl)和一个“Logic”(普通类)。首先,没有继承权。但现在我将其改写如下:(>)表示继承自:

  • SomeLogic->BaseLogic->IBaseLogic
  • SomePanel->BasePanel->UserControl,IBasePanel
问题是:这是一个好方法吗?这是我的面板代码(由于奇怪的继承错误而无法工作):

编辑1 解决了的。
我删除了界面,它现在可以工作了。我想我用错接口了。我仍然不知道何时使用抽象类以及何时使用接口。

您的编译器出现错误,因为正如编译器所述,
RegisterEvents()
Close()
的必需实现没有出现在您的
BaseClass
实现中

如果您想将实现推迟到子类,那么在基类中实现接口的正确方法是声明
抽象
实现,就像您对
InitializeComponent()所做的那样:

也就是说,请注意,简单地进行上述更改并不能获得要编译的代码。隐式实现的接口必须使用
public
成员实现。您不能使
RegisterEvents()
成为受保护的
成员。另一方面,如果您确实希望它是受保护的
成员,那么它可能不应该位于接口中,因为接口的设计成员是公共的

同样,您也遇到了
InitializeComponent()
方法的问题,您在基类中将该方法声明为
public
,但在派生的
MouseKeyRecord_面板中声明为
protected
。您不能更改虚拟成员重写的可访问性。将重写设置为
公共
方法,或将基类声明更改为
受保护

很可能您仍然不知道何时使用抽象类和接口。但第一步是知道如何做。:)至于“何时”,简而言之,抽象类和接口非常相似;主要的例外是,除了声明的接口之外,抽象类还可以(并且通常确实)包含一些实际实现(即,抽象类的
抽象
成员实际上是该类声明的接口…注意,与接口不同,抽象类的
抽象
成员不需要是
公共

当然,作为一个实际的类,任何给定的类型最多只能继承一个抽象类(如果已经继承了其他类,则没有)。您可以根据需要实现任意多的接口(有些人将此描述为也继承了一个接口,但我倾向于考虑继承实现和实现接口)


任何比这更深入的解释对于堆栈溢出来说都太宽泛了,最好留给教科书、博客和web上其他文章(包括MSDN上的C#文档)中的许多可用资源来解释.

如果您没有继承权,为什么要开始这样做?它目前不起作用吗?无论您试图实现什么,都可以通过组合而不是继承来更好地解决。嗯,它起了作用,但我想重新设计它们,使其“更好”。它们都有一些共同点。它们都有一个Close、InitializeComponent和RegisterEvents方法。我是这样学习的:如果你看到类有相同的方法,请使用基类,这样每个需要该方法的类都可以从中继承。
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.
    }
}
abstract class BasePanel : UserControl, IBasePanel  {
    public BasePanel() {
        InitializeComponent();
        RegisterEvents();
    }

    public abstract void InitializeComponent(); 
    public abstract void RegisterEvents();
    public abstract void Close();
}