c#继承多个父母
在这一刻,我有上述建设。扩展另一个基类的基类。基类由两个子类扩展。对于这两个子类,c#继承多个父母,c#,inheritance,multiple-inheritance,C#,Inheritance,Multiple Inheritance,在这一刻,我有上述建设。扩展另一个基类的基类。基类由两个子类扩展。对于这两个子类,baseTestClassMethod的实现是相同的。如果可以从两个父级进行扩展,我将创建一个类来扩展BaseTestClass1实现BaseTestClass1方法。然后,这两个子类将扩展BaseTestClass2和新类,这样我只需实现basetestclassmethod一次 当我添加另一个从BaseTestClass1扩展而来的BaseTestClass3(与BaseTestClass2级别相同)并从中创建
baseTestClassMethod
的实现是相同的。如果可以从两个父级进行扩展,我将创建一个类来扩展BaseTestClass1
实现BaseTestClass1方法
。然后,这两个子类将扩展BaseTestClass2
和新类,这样我只需实现basetestclassmethod
一次
当我添加另一个从BaseTestClass1扩展而来的BaseTestClass3(与BaseTestClass2级别相同)并从中创建子类时,我有更多重复的代码用于BaseTestClass1方法的实现。
如何使用正确的模式解决此问题
下面是一个更实用的示例:
namespace NUnitTestAbstract
{
public abstract class BaseTestClass1
{
public abstract void BaseTestClass1Method();
}
public abstract class BaseTestClass2 : BaseTestClass1
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodA() { }
public void SomeTestMethodB() { }
}
public abstract class BaseTestClass3 : BaseTestClass1
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodX() { }
public void SomeTestMethodY() { }
}
public class TestClass2A : BaseTestClass2
{
public override void BaseTestClass1Method()
{
// do stuff
}
}
public class TestClass2B : BaseTestClass2
{
public override void BaseTestClass1Method()
{
// do same stuff as TestClassA
}
}
public class TestClass3A : BaseTestClass3
{
public override void BaseTestClass1Method()
{
// do stuff
}
}
public class TestClass3B : BaseTestClass3
{
public override void BaseTestClass1Method()
{
// do same stuff as TestClass3A
}
}
}
使用接口而不是抽象类。您可以从多个接口继承,但只能从一个类继承。由于以下原因,不支持从两个类(或抽象类)派生。调用父方法时,类型为
D
的实例-它如何知道哪个父方法
使用接口和组合代替具有许多抽象类的深层继承树
- 用于定义API的接口
- 组合要通过具体的实现李>
TestClassb
这样的类可以创建所需逻辑的实例,或者更好地说仍然依赖于它的构造函数:
namespace NUnitTestAbstract
{
public interface IServer { }
public abstract class ServerBase
{
public abstract IServer GetServerInstance();
}
public abstract class SomeTests1Base : ServerBase
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodA() { }
public void SomeTestMethodB() { }
}
public abstract class SomeTests2Base : ServerBase
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodX() { }
public void SomeTestMethodY() { }
}
public class TestClass2A : SomeTests1Base
{
public override IServer GetServerInstance()
{
IServer serverX = null;
return serverX;
}
}
public class TestClass2B : SomeTests1Base
{
public override IServer GetServerInstance()
{
IServer serverX = null;
return serverX;
}
}
public class TestClass3A : SomeTests2Base
{
public override IServer GetServerInstance()
{
IServer serverY = null;
return serverY;
}
}
public class TestClass3B : SomeTests2Base
{
public override IServer GetServerInstance()
{
IServer serverY = null;
return serverY;
}
}
}
在您的代码注释中,您提到
TestClass2B
它与TestClassA
具有相同的行为,但它是从BaseTestClass2
派生的。您应该正确地考虑您的继承树。TestClass2B
是否应该是BaseTestClass2
的一种类型?还是应该是一种TestClassA
?
如果它实际上是一种“类”TestClassA
,则继承它
所有这些答案都是针对特定领域的,但我建议你阅读有关作文的内容:它将帮助你了解你的关系类型,以及什么是适合你的情况的正确设计
此外,还有一些好的设计模式可供查看,例如下面的State
,Strategry
,Decorator
在了解了
合成的优点以及何时使用它之后,您可以查看固体
和控制反转
,这将有助于将它们完美地结合在一起。使用其他人建议的界面:
public class Derived
{
public Derived(ILogic someDependentLogic) { }
}
我不明白为什么不重写BaseTestClass2中的BaseTestClass1方法
namespace NUnitTestAbstract
{
public interface IBaseTes1
{
void BaseTestClass1Method();
}
public abstract class BaseTestClass2 : IBaseTes1
{
void IBaseTes1.BaseTestClass1Method()
{
}
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodA() { }
public void SomeTestMethodB() { }
}
public class TestClassA : BaseTestClass2
{
}
public class TestClassb : BaseTestClass2
{
}
}
为了达到这样的目标,你可以使用不同的模式,比如
战略模式:
状态模式:您可以在BaseTestClass2中实现BaseTestClassMethod,以便TestClassA和TestClassB获得相同的实现。然而,根据您的需求,走这条路可能会导致继承失败
您可以通过其构造函数(依赖注入(DI))将实现BaseTestClass1的实例传递给BaseTestClass2,而不是从BaseTestClass1继承BaseTestClass2。然后在TestClassA和TestClassB中,只需调用注入实例的BaseTestClassMethod方法。这将您的继承级别降低到1
使用DI容器(如Autofac或Unity)将BaseTestClass1的正确实现注入BaseTestClass2的Decentant中
更新
从你的例子开始
public abstract class BaseTestClass2 : BaseTestClass1
{
public override void BaseTestClass1Method()
{
// do same stuff as TestClassA
}
}
var someTests1=newsometests1(newservera());
var someTests2=newsometests2(newserverb())
注意,我已经删除了抽象类,并将服务器实现注入到新实例中
我放弃了TestClass(1..n),因为我看不出有必要使用它们,但只有您知道答案
此外,我还动态编写了这段代码,因此它没有经过测试,也没有检查它是否编译,但您应该能够了解它的要点。希望有帮助。我没有找到正确的接口解决方案。BaseTestClass2实现两个测试方法,然后由两个子类共享。BaseTestClass1还应该有一个实现,我可以和两个子类共享。diamond问题几年前就解决了吗?我想Bob叔叔甚至讨论过它。@WernerKellens-看起来TestClassb
更像是TestClassA
的一种类型,而不是基本类型,那么也许你应该让它从TestClassA
派生出来。但是,您仍然会遇到深层继承树,这会降低代码的灵活性—使用组合有助于解决这一问题it@WernerKellens-这个答案帮助你解决问题了吗?@WernerKellens-很高兴听到:)SOLID真的让生活简单多了。我找不到正确的接口解决方案。BaseTestClass2实现两个测试方法,然后由两个子类共享。BaseTestClass1还应该有一个我可以和两个子类共享的实现。我想这是唯一的解决办法。我用一个扩展的例子编辑了这个问题。问题是BaseTestClass2不应该实现BaseTestClass1方法。如果BaseTestClass1方法真的是一样的,那么为什么不让BaseTestClass1具体化并在那里实现该方法呢?您可以对子类中可能不同的任何属性/方法进行受保护的重写。或者我错过了什么?谢谢,举个例子就好了!谢谢,不,我可以在我的实际实现中尝试一下,因为子类之间的实现可能不同。我已经改变了我的借口。实现与fo不同
namespace NUnitTestAbstract
{
public interface IServer { }
public class BaseServer()
{
private IServer _server;
public BaseServer(IServer server)
{
_server = server;
}
public IServer GetServerInstance()
{
return _server;
}
}
public class SomeTests1 : ServerBase
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodA() { }
public void SomeTestMethodB() { }
}
public class SomeTests2 : ServerBase
{
// not overriding BaseTestClass1Method, child classes should do
public void SomeTestMethodX() { }
public void SomeTestMethodY() { }
}
}
public class ServerA : IServer
{
//Implementation
}
public class ServerB : IServer
{
//Implementation
}