2015-07-11 44 views
0

我有一个关于如何在我的C#程序中正确使用接口和抽象类的问题。我有许多独立的“模块”(BeatsPerMinuteMeasurement,MouseRecorder,ClipboardHistory等)。他们都至少有一个面板(UserControl)和一个“逻辑”(普通类)。首先,没有继承。但是,现在我重写这样的:( - >)指继承:使用独立“模块”的接口和基类

  • SomeLogic - > BaseLogic - > IBaseLogic
  • SomePanel - > BasePanel - >用户控件,IBasePanel

的问题:这是一个好办法吗?这里是我的面板的代码(这是不奇怪的,因为继承错误的工作):

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 解决。 我删除了界面,现在它正在工作。我想我以错误的方式使用了接口。我仍然不知道何时使用抽象类以及何时使用接口。因为,因为编译器规定的RegisterEvents()Close()所需的实现并没有在你的BaseClass实施出现时

+0

如果你没有继承,你为什么要开始做呢?目前不工作吗?无论你试图达到什么样的目标,都可以用组合而不是继承来解决。 –

+0

好吧,它的工作,但我想重新设计它们使其“更好”。他们都有一些共同的东西。他们都有一个Close,InitializeComponent和RegisterEvents方法。我通过这种方式了解到:如果您看到类具有相同的方法,请使用基类,以便每个需要该方法的类都可以继承它。 – Need

回答

0

你的编译器错误。

如果你想推迟实施的子类,然后以正确的方式来实现在基类的接口是声明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_Panelprotected。您无法更改虚拟成员覆盖的可访问性。可以使覆盖为public方法,也可以将基类声明更改为protected

很可能是你仍然不知道何时使用抽象类和接口。但第一步是知道如何。 :)至于“何时”,简单的答案是抽象类和接口非常相似;主要的例外是一个抽象类可以(并且一般地)包括一些实际的实现,除了声明的接口(即抽象类的成员实际上是该类声明的接口,注意不同于接口,abstract成员抽象类不需要是public)。当然,作为一个实际的类,任何给定的类型最多可以继承一个抽象类(如果它已经继承了一些其他类,则它们都不会继承)。你可以实现尽可能多的接口,你想/需要(有人将此描述为继承接口,但我倾向于考虑继承实现和实现接口)。

更深入的解释是恕我直言对于堆栈溢出来说太广泛了,最好留给Web上的文本书籍,博客和其他文章(包括MSDN上的C#文档)中的许多资源。