C#接口和基类
我有一个C#接口和一个实现该接口的具体类。现在我想创建另一个实现该接口的类。很简单 然而,大多数方法在类中都是完全相同的,只有几个方法会真正改变 我不想复制我的第二个类中包含的第一个类中的所有逻辑 我如何创建第二个类,并在第一个类中使用逻辑,除了额外的东西 我的接口称为IEventRepository,我的第一个类称为BaseEvents。现在我想创建一个名为FooBarEvents的新类 我对FooBarEvents的类定义是:C#接口和基类,c#,oop,inheritance,C#,Oop,Inheritance,我有一个C#接口和一个实现该接口的具体类。现在我想创建另一个实现该接口的类。很简单 然而,大多数方法在类中都是完全相同的,只有几个方法会真正改变 我不想复制我的第二个类中包含的第一个类中的所有逻辑 我如何创建第二个类,并在第一个类中使用逻辑,除了额外的东西 我的接口称为IEventRepository,我的第一个类称为BaseEvents。现在我想创建一个名为FooBarEvents的新类 我对FooBarEvents的类定义是: public class FooBarEvents : Base
public class FooBarEvents : BaseEvents, IEventRepository
我的意图是在复制代码的每个方法中使用return base.Method()
我假设这是不正确的?因为
BaseEvents
已经实现了IEventRepository
,您不需要在FooBarEvents
中再次实现它FooBarEvents
自动继承BaseEvents
'实现。您可以让第二个类扩展第一个类。您的第一个类可以是抽象的,但只能实现接口中的常用方法。fooberavents
应该只需要从BaseEvents
继承,而不需要实现IEventRepository
,因为BaseEvents
已经实现了接口。如果需要更改FooBarEvents
中某些IEventRepository
方法的行为,只需重写这些方法即可
编辑:一些例子
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)
{ ... }
如果
IEventRepository
的BaseEvents
实现中的某个方法选择总是要维护相同的实现,那么您可以在BaseEvents
类中实现它们,并将可能更改为virtual
的方法标记出来。这样,如果FooBarEvents
希望更改其中一个方法的实现,它可以简单地覆盖它
关于将
IEventsRepository
添加到FooBarEvents
类,请注意:这样做是有效的。有关Jon Skeet的答案,请参阅。为什么不将基类中的方法定义为Virtual
,并覆盖子类中要更改的方法?使用继承:
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() {...}
}
baronstroids
将继承Bar
的所有行为,您可以通过在baronstroids
中重写它们来更改所需任何方法的特定行为(它们需要在基类Bar
中标记为虚拟)
通过这种方式,您将获得以下内容:
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.
这假设您想要更改属于
IFoo
接口的方法的特定行为。如果您只想将附加功能添加到baronstroids
,那么只需继承表单Bar
即可继承其所有功能,并添加所有必需的新方法来实现新功能。以下代码显示了如何使用抽象基类提供某些接口方法的通用实现,并为其他人提供自定义实现
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
}
}
公共接口IEventRepository
{
void方法1();
void方法2();
}
公共抽象类BaseEvents:IEventRepository
{
公共无效方法1()
{
Console.WriteLine(“这是共享功能”);
}
公开摘要无效方法2();
}
公共类实现1:BaseEvents
{
重写公共无效方法2()
{
Console.WriteLine(“Impl1.Method2”);
}
}
公共类实现2:BaseEvents
{
重写公共无效方法2()
{
Console.WriteLine(“Impl2.Method2”);
}
}
公共课程
{
静态void Main(字符串[]参数)
{
var implementations=new List{new Implementation1(),new Implementation2()};
foreach(实现中的var i)
{
WriteLine(i.GetType().Name);
控制台。写入(“\t”);
i、 Method1();//写入“这是共享功能”
控制台。写入(“\t”);
i、 Method2();//写入特定于类型的消息
}
}
}有几种不同的方法 一个。完全跳过接口,使其成为一个抽象类。这在工作时更简单,但您只能有一个基类这一事实限制了在C中的使用# 可以让一个类实现接口,另一个类从接口派生:
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;
}
}
让它们都重写一个抽象类,该抽象类提供一些常见行为:
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;
}
}
他们还可能使用与层次结构无关的静态帮助器类,但它提供了在实现功能时有用的方法
但要警惕这种模式:
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
即使
IEventRepository.Method1
的定义更加合理,上述内容也可能会导致混淆。确切地说,您为什么要使用接口?“您可以让您的第二个类扩展您的第二个类”-您的意思是“扩展您的第一个类”?我使用的是Ninject依赖项注入,它不想了解抽象类。您可以在容器中注册实现类-在下面的示例中是Implementation1和Implementation2。抽象类无法实例化,因此它们不能与容器一起工作。因此,如果我使用Bar使用IFoo并调用SpecificBehaviorMethod1,我想我会得到一个NotImplementedException,似乎Baronstroids做了Bar不做的事情?@Pual。请参见编辑以获取答案。简而言之,不行,Bar
和baronstroids
都必须实现SpecificBehaviorMethod1
,因为此方法是IFoo
合同的一部分。如果SpecificBehaviorMethod
是虚拟的,它将调用特定于您正在调用的实例的实际类型的实现。我明白了,但是FooBarEvents类将是特定于客户端的,并且可能还有10个未实现的方法
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