5. 是的,我說謊了。[New]
或許您已注意到,整個過程中我做了一個最大假設:我可以隨意修改 A 的原始碼!因此能輕易糾正非預期的多態行為。但實際情況是,我們不會每次那麼幸運。若僅得到包含類別 A 和介面 IC 的組件呢?那就需要使用介面重新映射。實際上 B2 就是用這技巧。來看具體情況:
介面 IC 規格不變。我們只知道類別 A 的宣告、成員列表與對應輸出:
Class class A : IC Output
Method public void M(); In class A
Method void IC.M(); In class A
現在需要實作一批繼承 A 的衍生類,但不希望同時繼承 A 對應方法實現,怎麼辦?簡單,先建立類別 AX 繼承 A 和 IC,在 AX 處理好相關事宜,再讓那批衍生類繼承 AX:
class AX : A, IC
{
// new 聲明與基類同名方法 M 無關
// virtual 為後代繼承鋪墊
public new virtual void M()
{
Console.WriteLine("In class AX");
}
void IC.M() { this.M(); }
}
class B1 : AX
{
public override void M() { Console.WriteLine("In class B1"); }
}
class B2 : AX
{
public override void M() { Console.WriteLine("In class B2"); }
}
測試程式:
class Program
{
static void Main(string[] args)
{
List<IC> cs = new List<IC>();
cs.Add(new A()); cs.Add(new AX()); cs.Add(new B1()); cs.Add(new B2());
foreach (IC c in cs) c.M();
Console.WriteLine();
List<AX> ace = new List<AX>();
ace.Add(new AX()); ace.Add(new B1()); ace.Add(new B2());
foreach (AX a in ace) a.M();
Console.ReadLine();
}
}
結果:
In class A
In class AX
In class B1
In class B2
In class AX
In class B1
In class B2
介面重新映射究竟是問題還是技巧,看您實際遭遇情況。若能靈活運用,確會帶來巨大便利!