[英]Object Inheritance, Sealed Method Overrides, and C#
我有一個由另一個程序集定義的抽象類(不可編輯):
public abstract class A
{
public void Run()
{
Go("Hello World");
}
protected virtual void Go(string message)
{
// Do Nothing
}
}
現在我有一個我想從這個實現Go()的類繼承的庫。 這里的訣竅是我不希望任何繼承自我的人能夠覆蓋我的Go()實現,但我也不想以任何方式更改簽名。 我實際上希望調用這兩個實現。 這是我到目前為止所得到的:
public abstract class B_Intercept : A
{
protected sealed override void Go(string message)
{
Console.WriteLine(message);
Go_Impl(message);
}
internal abstract void Go_Impl(string message);
}
public abstract class B : B_Intercept
{
protected new virtual void Go(string message)
{
}
internal override void Go_Impl(string message)
{
Go(message);
}
}
現在我的最終用戶可以將他們的類繼承從A切換到B而不起作用(除了我的Console.WriteLine)。
public class C : A // This can be changed to B with no other edits
{
protected override Go(string message)
{
// Do stuff
}
}
現在,原始庫可以被賦予C的實例,它將被裝箱為A,原始庫將調用Run()。 Run將使用B_Intercept的Go(),它將消息轉儲到控制台,然后調用Go_Impl()。 Go_Impl將在B中運行,它將調用B的Go(),它可以被C覆蓋。
這感覺非常迂回。
這些方法的一些安全性還有一個額外的好處(它們不能直接調用Go_Impl),但仍有漏洞(它們可以調用base.Go)。 我認為這些漏洞可以用第三層封閉,但我還沒試過,坦白說我認為這有點荒謬。 但它仍然感覺像很多樣板代碼。 B_Intercept還有一個蹩腳的副作用,需要公開而不是內部,這會以一種無法解釋的方式提升我的圖書館的表面區域。
有更簡單,更安全的方式嗎?
這里的問題是你正在嘗試做一些不是原始類開發人員的意圖。
Go
已作為virtual
方法提供,現在您正在嘗試隱藏它,同時希望將其保持為OO盡可能 - ( 更新 )而不僅僅是,您還關注繼承類調用基本方法。 我真誠地祝賀你的努力,關心和關注,但有些事情必須給予 。
要么你必須使用composition
包裝的A類,並提供了你打算提供,適合你的設計的接口, 或者你必須使用inheritance
和接受其短到來,主要是從事實出現你真的改變預期的行為班級。 對於我的兩分錢,我會選擇第一個選項: composition
。 在一天結束時,這正是你想要實現的目標。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.