三、虛方法
當類中的方法聲明前加上了virtual 修飾符,我們稱之為虛方法,反之為非虛。使用了virtual 修飾符後,不允許再有static, abstract, 或override 修飾符。
樣本1:帶有虛方法的類
using System ;
public class DrawingBase
{
public virtual void Draw( )
{ Console.WriteLine("這是一個虛方法!") ; }
}
說明:這裡定義了DrawingBase類。這是個可以讓其他對象繼承的基類。該類有一個名為Draw( )的方法。Draw( )方法帶有一個virtual修飾符,該修飾符表明:該基類的衍生類別可以重載該方法。DrawingBase類的 Draw( )方法完成如下事情:輸出語句"這是一個虛方法!"到控制台。
樣本2:帶有重載方法的衍生類別
using System ;
public class Line : DrawingBase
{
public override void Draw( )
{ Console.WriteLine("畫線.") ; }
}
public class Circle : DrawingBase
{
public override void Draw( )
{ Console.WriteLine("畫圓.") ; }
}
public class Square : DrawingBase
{
public override void Draw( )
{ Console.WriteLine("畫正方形.") ; }
}
說明:上面程式定義了三個類。這三個類都派生自DrawingBase類。每個類都有一個同名Draw( )方法,這些Draw( )方法中的每一個都有一個重載修飾符。重載修飾符可讓該方法在運行時重載其基類的虛方法,實現這個功能的條件是:通過基類類型的指標變數來引用該類。
對於非虛的方法,無論被其所在類的執行個體調用,還是被這個類的衍生類別的執行個體調用,方法的執行方式不變。而對於虛方法,它的執行方式可以被衍生類別改變,這種改變是通過方法的重載來實現的。
下面的例子說明了虛方法與非虛方法的區別。
using System ;
class A
{
public void F( ) { Console.WriteLine("A.F") ; }
public virtual void G( ) { Console.WriteLine("A.G") ; }
}
class B: A
{
new public void F( ) { Console.WriteLine("B.F") ; }
public override void G( ) { Console.WriteLine("B.G") ; }
}
class Test
{
static void Main( )
{
B b = new B( ) ;
A a = b;
a.F( ) ;
b.F( ) ;
a.G( ) ;
b.G( ) ;
}
}
例子中,A 類提供了兩個方法:非虛的F 和虛方法G 。類B 則提供了一個新的非虛的方法F, 從而覆蓋了繼承的F; 類B 同時還重載了繼承的方法G 。那麼輸出應該是:A.F B.F B.G B.G
注意到本例中,方法a.G( ) 實際調用了B.G,而不是A.G,這是因為編譯時間值為A,但運行時值為B ,所以B 完成了對方法的實際調用。