[英]c# inheritance multiple parents
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
}
}
}
這時我有上面的結構。 擴展另一個基類的基類。 基類由兩個子類擴展。 BaseTestClass1Method
的實現對於兩個子類是相同的。 如果可以從兩個父BaseTestClass1
擴展,我將創建一個擴展BaseTestClass1
的類,實現BaseTestClass1Method
。 這兩個子類將擴展BaseTestClass2
和新類,這樣我只需要實現一次BaseTestClass1Method
當我添加另一個BaseTestClass3(與BaseTestClass2相同的級別)從BaseTestClass1擴展並從中創建子類時,我有更多重復的代碼用於實現of BasetestClass1Method。 如何用正確的模式解決這個問題?
這是一個更實施的例子:
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;
}
}
}
由於Diamond問題,不支持從兩個類(或抽象類)派生。 調用父方法時類型D
的實例 - 它如何知道哪個父類?
而不是具有許多抽象類的深度繼承樹使用接口和組合。
您的邏輯是通過某個接口定義的,並且具有針對該特定邏輯的不同具體類型。 然后像TestClassb
這樣的類可以創建所需邏輯的實例,或者更好地依賴於它的構造函數:
public class Derived
{
public Derived(ILogic someDependentLogic) { }
}
在你的代碼注釋中,你說TestClass2B
它具有與TestClassA
相同的行為,但它取而代之的是BaseTestClass2
。 您應該正確考慮繼承樹。 TestClass2B
應該是BaseTestClass2
嗎? 或者它應該是一種TestClassA
? 如果它實際上是一種“類型” TestClassA
那么繼承它。
所有答案都是針對特定領域的,但我建議您閱讀有關構圖的內容:它將幫助您了解您擁有的關系類型以及適合您情況的正確設計。
另外也有一些很好的設計模式來看待,如State
, Strategry
, Decorator
下dofactory
在看到Composition
的優點以及何時使用它之后,你可以看看SOLID
和Inversion Of Control
它將有助於它們很好地融合在一起。
使用接口而不是抽象類。 您可以從多個接口繼承,但只能從一個類繼承。
我不明白你為什么不在BaseTestClass2中重寫BaseTestClass1Method
public abstract class BaseTestClass2 : BaseTestClass1
{
public override void BaseTestClass1Method()
{
// do same stuff as TestClassA
}
}
要實現這樣的目標,您可以使用不同的模式
戰略模式: http : //www.dofactory.com/net/strategy-design-pattern
您可以在BaseTestClass2中實現BaseTestClass1Method,以便TestClassA和TestClassB獲得相同的實現。 但是,根據您的要求,走這條路可能會繼承地獄。
您可以通過其構造函數(依賴注入(DI))將實現BaseTestClass1的實例傳遞給BaseTestClass2,而不是從BaseTestClass1繼承BaseTestClass2。 然后在TestClassA和TestClassB中簡單地調用實例中注入的BaseTestClass1Method方法。 這會將繼承級別降低到1。
使用諸如Autofac或Unity之類的DI容器將BaseTestClass1的正確實現注入BaseTestClass2的后代。
UPDATE
從你的例子開始吧
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
}
var someTests1 = new SomeTests1(new ServerA()); var someTests2 = new SomeTests2(new ServerB());
請注意,我已刪除抽象類並將服務器實現注入新實例。
我放棄了TestClass(1..n),因為我看不到它們的需要,但只有你能知道答案。
此外,我已經編寫了這段代碼,所以它還沒有經過測試,也沒有檢查它是否編譯,但你應該能夠得到它的要點。 希望能幫助到你。
使用其他人建議的界面:
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
{
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.