简体   繁体   English

C#表继承Abstract类并实现接口。

[英]C# Form that inherit Abstract class AND implements interface.

I need to have a multiple Form classes in my project. 我需要在我的项目中有多个Form类。 So was thinking about putting everything those forms will have in common, together in abstract class. 因此,考虑将这些形式的所有内容放在一起,在抽象课程中。 This class will have inheriet Form class and also an interface. 该类将具有继承Form类和接口。 Sth like that: 那样的:

public interface IMyForm
{
void Init();
}

public abstract class AMyForm : Form, IMyForm
{
    void IBrowser.Init()
    {
        throw new NotImplementedException();
    }     
}

public partial class MainClass : AMyForm 
{

// But here the warning is shown (That i have to add override keyword),
// but when i do, The error is shown that i cannot override from non abstract thing 
    public void Init() 
    {
    }
}

Could u tell me how to achieve that ? 你能告诉我怎么做到的吗?

While Jon Skeets answer is correct for general programming, I would advise AGAINST using abstract classes on Forms and User controls. 虽然Jon Skeets的答案对于一般编程是正确的,但我建议AGAINST使用表单和用户控件上的抽象类。 First issue is, that designer won't be able to create an instance of the abstract class and thus will not be able to display a form that inherits FROM the abstract form in the designer. 第一个问题是,该设计器将无法创建抽象类的实例,因此无法在设计器中显示继承FROM抽象形式的表单。 Meaning that you will not be able to add new controls to form via designer, unless - as suggested in comments below - you add a surrogate class that implements the abstract class and is then used as a base for other inherited forms, eg: AbstractMyForm -> MyFormSurrogate -> MyForm . 这意味着您将无法通过设计器向表单添加新控件, 除非 - 如下面的注释中所示 - 添加实现抽象类的代理类,然后将其用作其他继承表单的基础,例如: AbstractMyForm -> MyFormSurrogate -> MyForm

Second and larger issue is in my opinion, that this means that you are trying to stick logic into forms. 在我看来,第二个也是更大的问题,这意味着你试图将逻辑粘贴到表格中。 This is usually not desired, especially if you end up coupling your business logic to your display technology, in this case Winforms . 通常是不希望的,特别是如果您最终将业务逻辑耦合到您的显示技术,在这种情况下是Winforms My advice would be to try to use the Model View Presenter pattern to separate as much logic as possible in ordinary classes (using abstract classes, interfaces, etc.) and then data bind them to the form. 我的建议是尝试使用Model View Presenter模式在普通类中使用尽可能多的逻辑(使用抽象类,接口等),然后将数据绑定到表单。 If there are visual parts that are shared (eg: a group of checkboxes), make user controls for such parts and just reuse them on forms. 如果存在共享的可视部分(例如:一组复选框),请对这些部分进行用户控制,并在表单上重复使用它们。

I hope I didn't presume too much of your knowledge of working with winforms, but I had similar questions when I started getting into GUI development. 我希望我没有过多地介绍你使用winforms的知识,但是当我开始进入GUI开发时我遇到了类似的问题。

You just want to not use explicit interface implementation in your abstract class: 您只是想在抽象类中使用显式接口实现:

public abstract class AMyForm : Form, IMyForm
{
    public virtual void Init()
    {
        throw new NotImplementedException();
    }     
}

Or just make it abstract: 或者只是把它抽象化:

public abstract class AMyForm : Form, IMyForm
{
    public abstract void Init();
}

In both cases, you then just override it in your concrete class. 在这两种情况下,您只需在具体类中覆盖它。

Alternatively, if you really want to use explicit interface implementation in your abstract class, you should use it again in your concrete class: 或者,如果您真的想在抽象类中使用显式接口实现,则应该在具体类中再次使用它:

public partial class MainClass : AMyForm, IMyForm
{
    void IMyForm.Init() 
    {
        // Stuff
    }
}

The downside is that any subclass of AMyForm which doesn't do this will basically have the broken IMyForm implementation. 缺点是AMyForm任何子类都没有这样做,基本上会有破坏的IMyForm实现。 Using the first approach is better here. 使用第一种方法在这里更好。

EDIT: Or, as per supercat's suggestion: 编辑:或者,根据supercat的建议:

public abstract class AMyForm : Form, IMyForm
{
    void IBrowser.Init()
    {
        InitImpl();
        // And anything else you need...
    }     

    // Or abstract...
    protected virtual void InitImpl()
    {
    }
}

Then override InitImpl in your concrete class. 然后在具体类中重写InitImpl

With abstract classes not showing in design view; 抽象类没有在设计视图中显示; you can get around it by adding a compiler if statement to the abstract class to make it not abstract at design time. 你可以通过向抽象类添加编译器if语句来使它在设计时不抽象。

#if RELEASE
    public abstract class AbstractForm : Form, IInterface
#else
    public class AbstractForm : Form, IInterface
#endif
    {
        // Your abstract code here.
    }

It's a nice little hack that works quite effectively. 这是一个非常有效的小黑客。 You can use the same trick to switch between virtual and abstract methods between design time and run time. 您可以使用相同的技巧在设计时和运行时之间切换虚方法和抽象方法。

ADDENDUM: 附录:

It should be noted that using abstract forms is unneeded. 应该注意,不需要使用抽象形式。 It is more efficient and creates less potential problems to inherit from a non-abstract Form. 从非抽象表单继承它会更有效并且创建更少的潜在问题。

public partial class Screen : Form, IInterface
{
    // Base Class here, complete with .designer.cs and .resx
    public Screen()
    {
        InitialiseComponent();
    }

    #region IInterface imported methods
    public partial void SomeMethod()
    {
        // Do something.
    }
    #endregion
}

And then, if you wanted to create a Logon Screen for example: 然后,如果您想创建一个登录屏幕,例如:

public partial class LogonScreen : Screen, IInterface
{
    // Derived Class here, complete with .designer.cs and .resx
    public Screen()
    {
        InitialiseComponent();
    }

    #region IInterface imported methods
    public partial void SomeMethod()
    {
        // Do more somethings!
    }
    #endregion
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM