简体   繁体   English

C#:Interface和Abstract来启用实现和覆盖

[英]C#: Interface and Abstract to enable Implement and Override

I've got to design about 5 different classes. 我必须设计大约5个不同的课程。

A lot of the parts of these classes will be very similar, but they will have slight differences (of course). 这些类的许多部分将非常相似,但它们会有轻微的差异(当然)。

If I write an interface that each of my designed classes implement, then each abstract method in the interface has to be completely written. 如果我写的interface ,每个我设计的类的实现,那么每个abstract的方法interface必须完全写入。

If I write a base class that each of my designed classes derives from, then each class will automatically have some functionality in the virtual method that I create in the base class, but they would all need to be overridden, calling the base functionality, to include the slight differences. 如果我编写一个我设计的每个类派生的base类,那么每个类将自动在我在base类中创建的virtual方法中具有一些功能,但是它们都需要被覆盖,调用base功能,包括细微的差异。

Is there a way to combine these features? 有没有办法结合这些功能? I like requiring the interface 's methods to be implemented, but I also like having set features pre-programmed by a base class. 我喜欢要求实现interface的方法,但我也喜欢设置由base类预编程的功能。

I've looked at many examples here and elsewhere, but it does not look like anyone does what I am describing. 我在这里和其他地方看过很多例子,但看起来并没有人像我所描述的那样。 Is it even possible? 它甚至可能吗?

EDIT: So, given this: 编辑:所以,鉴于此:

abstract class Base
{
    virtual protected void OptionallyOverridable() {}
    abstract protected void SubclassMustImplement();
}

...is there a way to write something that does like this: ...有没有办法写出这样的东西:

abstract class Base2
{
    DataEventType EventType;
    DataChangedEventHandler OnDataChange;

    virtual protected void OptionallyOverridable() {}
    abstract protected void SubclassMustImplement() {
      // values here are guaranteed
    }
}

C# allows a class to both inherit from a base class and implement an interface, so why not just do both? C#允许类从基类继承并实现接口,那么为什么不这样做呢?

public interface IFoo
{
    public void Bar();
    public bool Baz();
}

public abstract class BaseFoo : IFoo
{
    //fields/properties used in all classes
    public void Bar()
    { //Implementation }

    public bool Baz()
    { //Implementation }
}

public class DerivedFoo : BaseFoo, IFoo {...}

AllenG got my plus one, but since I had already typed this out, here is a lengthier and more explicit demonstration of the concept... AllenG得到了我的加号,但由于我已经输入了这个,这里有一个更长,更明确的概念演示......

Define your interface... 定义你的界面......

public interface IFoo
{
    void DoIt();
    void DoItWithoutDefaultBehavior();
}

Define a base class that implements the interface with some default behaviors, or perhaps some methods don't have a default behavior... 定义一个实现具有某些默认行为的接口的基类,或者某些方法可能没有默认行为......

public abstract class BaseFoo : IFoo
{
    public virtual void DoIt()
    {
         // Base behavior
         Console.WriteLine("base");
    }

    // This one has no base behavior
    public abstract void DoItWithoutDefaultBehavior();
}

Some of your subclasses might use those default behaviors ... 您的某些子类可能会使用这些默认行为......

public class DerivedFoo1 : BaseFoo, IFoo
{
    // Doesn't override DoIt, takes BaseFoo

    public override void DoItWithoutDefaultBehavior()
    {
        Console.WriteLine("foo1");
    }
}

Others might add to them ... 其他人可能会加入他们......

public class DerivedFoo2 : BaseFoo, IFoo
{
    public override void DoIt()
    {
        base.DoIt();
        // Additional stuff
        Console.WriteLine("derived");
    }

    public override void DoItWithoutDefaultBehavior()
    {
        Console.WriteLine("foo2");
    }
}

You can call the methods through the class or the interface. 您可以通过类或接口调用方法。

void Main()
{
    var foo1 = new DerivedFoo1();
    foo1.DoIt();

    var foo2 = new DerivedFoo2();
    foo2.DoIt();

    IFoo foo1AsFoo = new DerivedFoo1();
    foo1AsFoo.DoIt();

    IFoo foo2AsFoo = new DerivedFoo2();
    foo2AsFoo.DoIt();
}

See also: Eric Lippert's post which discusses whether DerivedFoo1 and DerivedFoo2 should restate that they implement IFoo when BaseFoo already says so. 另请参阅: Eric Lippert的文章 ,讨论DerivedFoo1DerivedFoo2是否应重述他们在BaseFoo已经这样说时实现IFoo They do in my example for the sake of being explicit. 为了明确起见,他们在我的例子中做了。

EDIT It's definitely possible to add events to the interface. 编辑绝对可以在界面中添加事件。 I made the following changes to my example. 我对我的例子进行了以下更改。 You could make similar changes: 您可以进行类似的更改:

  • To interface IFoo , add event EventHandler TheEvent; interface IFoo ,添加event EventHandler TheEvent;
  • To BaseFoo , add public event EventHandler TheEvent; BaseFoo ,添加public event EventHandler TheEvent;
  • To BaseFoo.DoIt , add if (TheEvent != null) { var args = new EventArgs(); TheEvent(this, args); } BaseFoo.DoIt ,添加if (TheEvent != null) { var args = new EventArgs(); TheEvent(this, args); } if (TheEvent != null) { var args = new EventArgs(); TheEvent(this, args); }
  • Add public void TheHandler(object sender, EventArgs e) { Console.WriteLine("Fired."); } 添加public void TheHandler(object sender, EventArgs e) { Console.WriteLine("Fired."); } public void TheHandler(object sender, EventArgs e) { Console.WriteLine("Fired."); }
  • To Main , add foo1.TheEvent += TheHandler; Main ,添加foo1.TheEvent += TheHandler;

The output now becomes 输出现在变成了

base
Fired.
base
derived
base
base
derived

Yes and you already answered yourself. 是的,你已经回答了自己。 You will do both: 你会做两件事:

  • Have a base class with basic implementation 有一个基本实现的基类
  • Have child classes (or base class, why not?) implement the interfaces you want. 有子类(或基类,为什么不?)实现你想要的接口。

You can mix both interface and abstract, I think what you want is something like this 你可以混合使用界面和抽象,我想你想要的是这样的

public interface IFoo
{
    void ImplementMe();
    int ImplementId { get; }
}

public abstract class BaseFoo : IFoo
{
    public virtual void ImplementMe()
    {
        CommonStuff();
    }

    public abstract int ImplementId { get; }

    private void CommonStuff()
    {
        // ... do stuff ?
    }
}

public sealed class FooImplementationA : BaseFoo
{
    public override int ImplementId { get { return 0; } }

    public override void ImplementMe()
    {
        MoreStuff();
        base.CommonStuff();
    }

    private void MoreStuff()
    {
        // ... do more stuff.
    }
}

public sealed class FooImplementationB : BaseFoo
{
    public override int ImplementId { get { return 1; } }

    public override void ImplementMe()
    {
        DifferentStuff();
        base.CommonStuff();
    }

    private void DifferentStuff()
    {
        // ... do different stuff.
    }
}

but then again you don't really need the interface and can simply get away with using the BaseFoo abstract class 但是你再也不需要界面了,可以简单地使用BaseFoo抽象类

The 'abstract' keyword is what you are looking for. 'abstract'关键字是您正在寻找的。

    abstract class Base
    {
        virtual protected void SubclassCanCallAndOptionallyOverride() {}
        abstract protected void SubclassMustBeImplement();
    }

For more details: http://msdn.microsoft.com/en-us/library/ms173150.aspx 有关更多详细信息,请访问: http//msdn.microsoft.com/en-us/library/ms173150.aspx

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

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