15.4.4 接口實現的繼承機制
一個類繼承了它的基類提供的所有接口的實現
如果不顯式地重新實現接口,派生類就無法改變從基類中繼承來的接口映射。
interface IControl { void Paint(); } class Control:IControl { public void Paint(){...} } class TextBox:Control { new public void Paint(){...} }
上面的例子中,TextBox中的Paint方法覆蓋了Control中的Paint方法,但卻沒有改變Control.Paint對IControl.Paint的映射,並且在類的實例和接口的實例中對Paint方法的調用會產生下面這樣的結果:
Control c=new Control(); TextBox t=new TextBox(); IControl ic=c; IControl it=t; c.Paint(); //invokes Control.Paint(); t.Paint(); //invokes TextBox.Paint(); ic.Paint(); //invokes Control.Paint(); it.Paint(); //invokes Control.Paint();
但是,當一個interface方法被映射到類中的一個虛方法時,派生類就可以重載這個虛方法,並且改變這個接口的實現。我們改寫一下上例中的代碼:
interface IControl { void Paint(); } class Control:IControl { public virtual void Paint(){...} } class TextBox:Control { public override void Paint(){...} } 上面代碼的實際效果是: Control c=new Control(); TextBox t=new TextBox(); IControl ic=c; IControl it=t; c.Paint(); //調用Control.Paint(); t.Paint(); //調用TextBox.Paint(); ic.Paint(); //調用Control.Paint(); it.Paint(); //調用TextBox.Paint();
因為顯式說明的接口成員不能被聲明為虛的,因此無法重載顯式說明的接口實現。這時最好采用顯式說明的接口實現來調用另一個方法,這個被調用的方法可以被聲明為虛的,允許被派生類重載。例:
interface IControl { void Paint(); } class Control:IControl { void IControl.Paint(){PaintControl();} protected virtual void PaintControl(){...} } class TextBox:Control { protected override void PaintControl(){...} }
這裡,從Control中派生的類可以通過重載PaintControl方法來具體實現IControl.Paint。