C# 接口和基类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8913095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 05:08:32  来源:igfitidea点击:

C# Interface and base classes

c#oopinheritance

提问by Paul

I have a C# interface, and a concrete class that implements that interface. I now want to create another class that implements that interface. Simple enough.

我有一个 C# 接口和一个实现该接口的具体类。我现在想创建另一个实现该接口的类。足够简单。

However, most methods will be exactly the same in the classes, and only a couple of methods will actually change.

但是,类中的大多数方法将完全相同,只有少数方法会实际更改。

I don't want to duplicate all of the logic in my 2nd class that is contained in my first.

我不想复制我的第一个类中包含的第二个类中的所有逻辑。

How do I create the 2nd class, and use the logic in my first class except for the extra stuff?

我如何创建第二堂课,并在我的第一堂课中使用逻辑,除了额外的东西?

My interface is called IEventRepository, and my 1st class is called BaseEvents. I now want to create a new class called FooBarEvents.

我的接口称为 IEventRepository,我的第一个类称为 BaseEvents。我现在想创建一个名为 FooBarEvents 的新类。

My class definition for FooBarEvents is:

我对 FooBarEvents 的类定义是:

public class FooBarEvents : BaseEvents, IEventRepository

My intention was to then use the return base.Method() in each method that duplicates the code.

我的意图是然后在每个复制代码的方法中使用返回 base.Method() 。

I'm assuming this isn't correct?

我假设这不正确?

采纳答案by Esoteric Screen Name

FooBarEventsshould only need to inherit from BaseEvents, not also implement IEventRepository, as BaseEventsalready implements the interface. If you need to change the behavior of some IEventRepositorymethods in FooBarEvents, just override those methods.

FooBarEvents应该只需要继承自BaseEvents,而不是实现IEventRepository,因为BaseEvents已经实现了接口。如果您需要更改 中某些IEventRepository方法的行为FooBarEvents,只需覆盖这些方法。

Edit: some examples

编辑:一些例子

interface IEventRepository
{
   void CommonMethodA();
   void CommonMethodB();
   void ImplentationSpecificMethod();
}

abstract class BaseEvents : IEventRepository
{
   public void CommonMethodA()
   { ... }

   public virtual void CommonMethodB()
   { ... }

   public abstract void ImplementationSpecificMethod();

   public void BaseEventsMethod()
   { ... }

   public void BaseEventsMethod2()
   { ... }
}

class FooBarEvents : BaseEvents
{
   public override void CommonMethodB()
   { 
      // now FooBarEvents has a different implementation of this method than BaseEvents
   }

   public override void ImplementationSpecificMethod()
   { 
      // this must be implemented
   }

   public new void BaseEventsMethod2()
   { 
      // this hides the implementation that BaseEvents uses
   }

   public void FooBarEventsMethod()
   { 
      // no overriding necessary
   }
}

// all valid calls, assuming myFooBarEvents is instantiated correctly
myFooBarEvents.CommonMethodA()
myFooBarEvents.CommonMethodB()
myFooBarEvents.BaseEventsMethod();
myFooBarEvents.BaseEventsMethod2();
myFooBarEvents.FooBarEventsMethod();
myFooBarEvents.ImplementationSpecificMethod();

// use the contract thusly:
void DoSomethingWithAnEventRepository(BaseEvents events)
{ ... }

回答by Chris Shain

Since BaseEventsalready implements IEventRepository, you don't need to implement it again in FooBarEvents. FooBarEventsautomatically inherits BaseEvents' implementation.

由于BaseEvents已经实现了IEventRepository,您不需要在FooBarEvents. FooBarEvents自动继承BaseEvents' 实现。

回答by Sachin Kainth

You can make your second class extend your first class. Your first class can be abstract but only implement the common methods from the interface.

你可以让你的第二堂课扩展你的第一堂课。您的第一个类可以是抽象的,但只能实现接口中的通用方法。

回答by Samuel Slade

If a certain selection of methods in the BaseEventsimplementation of IEventRepositoryare alwaysgoing to maintain the same implementation, then you can just implement them in the BaseEventsclass and mark the ones that mightchange as virtual. That way, if FooBarEventswishes to change the implementation of one of the methods, it can simply override it.

如果在方法的选择一定BaseEvents的执行IEventRepository始终要保持相同的实现,那么你可以实现它们的BaseEvents类和标记的那些可能的变化virtual。这样,如果FooBarEvents希望更改其中一个方法的实现,它可以简单地覆盖它。

Just a note with regards to adding IEventsRepositoryto your FooBarEventsclass: it is valid to do that. See herefor a Jon Skeet answer about it.

只是关于添加IEventsRepository到您的FooBarEvents班级的说明:这样做是有效的。见这里的乔恩斯基特回答一下吧。

回答by pencilCake

Why don't you define your methods in the base class as Virtualand overridethe ones that you want to change in the child class?

为什么不在基类中定义方法Virtual覆盖子类中要更改的方法?

回答by InBetween

Use inheritance:

使用继承:

public interface IFoo
{
    void GeneralBehaviorMethod1();
    void GeneralBehaviorMethod2();
    void SpecificBehaviorMethod1();
}

public class Bar: IFoo
{
     public void GeneralBehaviorMethod1() {...}
     public void GeneralBehaviorMethod2() {...}

     public virtual void SpecificBehaviorMethod1() {...}
     ...
}

public class BarOnSteroids: Bar
{
    public override void SpecificBehaviorMethod1() {...}
}

BarOnSteroidswill inherit all behavior of Barand you can alter the specific behavior of any methods you need by overriding them in BarOnSteroids(they need to be marked as virtual in the base class Bar).

BarOnSteroids将继承的所有行为,Bar您可以通过覆盖它们来改变您需要的任何方法的特定行为BarOnSteroids(它们需要在基类中标记为虚拟Bar)。

This way you would have the following:

这样,您将拥有以下内容:

IFoo iFoo = new Bar();
iFoo.SpecificBehaviorMethod1(); //Bar implementation will be called;

IFoo iFoo = new BarOnSteroids();
iFoo.SpecificBehaviorMethod1(); //BarOnSteroids implementation will be called.
iFoo.CommonBehaviorMethod1(); //Bar implementation will be called.

Bar bar = new BarOnSteroids();
bar.SpecificBehaviorMethod1(); //BarOnSteroids implementation will be called.
bar.CommonBehaviorMethod1(); //Bar implementation will be called.

This assumes you want to change specific behavior of methods that are part of the IFoointerface. If all you want is to add additional functionality to BarOnSteroidsthen simply inherit form Barto inherit all it's functionality and add all required new methods to implement the new functionality.

这假设您要更改作为IFoo接口一部分的方法的特定行为。如果您只想添加额外的功能,BarOnSteroids那么只需继承 formBar来继承它的所有功能,并添加所有必需的新方法来实现新功能。

回答by Jason

The following code shows how to provide a common implementation of some interface methods with an abstract base class, and provide custom implementations for others.

下面的代码展示了如何使用抽象基类提供一些接口方法的通用实现,并为其他的提供自定义实现。

public interface IEventRepository
{
  void Method1();
  void Method2();
}

public abstract class BaseEvents : IEventRepository
{
  public void Method1() 
  {
    Console.WriteLine("This is shared functionality");
  }

  public abstract void Method2();
}

public class Implementation1 : BaseEvents
{
  override public void Method2()
  {
    Console.WriteLine("Impl1.Method2");
  }
}

public class Implementation2 : BaseEvents
{
  override public void Method2()
  {
    Console.WriteLine("Impl2.Method2");
  }
}

public class Program
{
  static void Main(string[] args)
  {
    var implementations = new List<IEventRepository> { new Implementation1(), new Implementation2() };

    foreach (var i in implementations) 
    {
       Console.WriteLine(i.GetType().Name);
       Console.Write("\t");
       i.Method1();  // writes 'This is shared functionality'

       Console.Write("\t");
       i.Method2(); // writes type specific message
    }
  }

}

}

回答by Jon Hanna

There's a few different approaches.

有几种不同的方法。

One. Skip the interface entirely, and make it an abstract class. This is simpler when it works, but the fact that you can only have one base class restricts use in C#

一。完全跳过接口,并使其成为抽象类。这在工作时更简单,但您只能拥有一个基类这一事实限制了在 C# 中的使用

public abstract class EventRepository
{
  public abstract int MustBeOverridden(string str);//classes have to override this
  public virtual int CanBeOverridden(int i)//classes can override but may choose not to.
  {
    return 4;
  }
  public int CannotOverride(string str)//this is always the same
  {
    return MustBeOverridden(str) + 3;//can make use of this
  }
}

You can have one class implement the interface, and another derive from it:

您可以让一个类实现接口,另一个类从它派生:

public interface IEventRepository
{
  int Method1(string str);
  int Method2(string str);
}

public class EventClass1 : IEventRepository
{
  public int Method1(string str)//can't be overridden as not marked virtual
  {
    return 1;
  }
  public virtual int Method2(string str)//can be overridden
  {
    return 2;
  }
}

public class EventClass2 : EventClass1
{
  public override int Method2(string str)
  {
    return -2;
  }
}

Have them both override an abstract class that gives some common behaviour:

让它们都覆盖一个抽象类,该类提供一些常见的行为:

public abstract class EventClass : IEventRepository
{
  public abstract int Method1(string str);
  public int Method2(string str)
  {
    return 2;
  }
}

public class EventClass1 : EventClass
{
  public override int Method1(string str)
  {
    return 1;
  }
}
public class EventClass2 : EventClass
{
  public override int Method1(string str)
  {
    return -1;
  }
}

They might also use a static helper class that has nothing to do with the hierarchy, but which does provide methods that are useful in implementing the functionality.

它们也可能使用与层次结构无关的静态帮助器类,但它确实提供了对实现功能有用的方法。

Be wary though of this pattern:

小心这种模式:

public class EventClass1 : IEventRepository
{
  public int Method1(string str)//not override-able
  {
    return 1;
  }
  public int Method2(string str)//not override-able
  {
    return 2;
  }
}
public class EventClass2 : EventClass1, IEventRepository
{
  //We really want our own Method1!
  public new int Method1(string str)
  {
    return 3;
  }
  int IEventRepository.Method1(string str)
  {
    return -1;
  }
}

EventClass2 e2 = new EventClass2();
EventClass1 e1 = e2;
IEventRepository ie = e2;
Console.WriteLine(e2.Method1(null));//3
Console.WriteLine(e1.Method1(null));//1
Console.WriteLine(ie.Method1(null));//-1

Even when IEventRepository.Method1is defined more sensibly, the above is likely to lead to confusion.

即使IEventRepository.Method1定义更合理,上述内容也可能导致混淆。