抽象(abstract)方法在邏輯上類似於虛方法,只是不能像虛方法那樣被調用,而只是一個接口的聲明而非實現。抽象方法沒有類似於{…}這樣的方法實現,也不允許這樣做。抽象方法同樣不能是靜態的。含有抽象方法的類一定是抽象類,也一定要加abstract類修飾符。但抽象類並不一定要含有抽象方法。繼承含有抽象方法的抽象類的子類必須覆蓋並實現(直接使用override)該方法,或者組合使用abstract override使之繼續抽象,或者不提供任何覆蓋和實現。後兩者的行為是一樣的。看下面的例子:
//abstract1.cs
// csc /t:library abstract1.cs
using System;
abstract class Parent
{
public abstract void F();
public abstract void G();
}
abstract class Child: Parent
{
public abstract override void F();
}
abstract class Grandson: Child
{
public override void F()
{
Console.WriteLine("Grandson.F");
}
public override void G()
{
Console.WriteLine("Grandson.G");
}
}
抽象方法可以抽象一個繼承來的虛方法,我們看下面的例子:
//abstract2.cs
// csc /t:library abstract2.cs
using System;
class Parent
{
public virtual void Method()
{
Console.WriteLine("Parent.Method");
}
}
abstract class Child: Parent
{
public abstract override void Method();
}
abstract class Grandson: Child
{
public override void Method()
{
Console.WriteLine("Grandson.Method");
}
}
歸根結底,我們抓住了運行時綁定和編譯時綁定的基本機理,我們便能看透方法呈現出的種種overload,virtual,override,sealed,abstract等形態,我們才能運用好方法這一利器!
外部方法
C#引入了extern修飾符來表示外部方法。外部方法是用C#以外的語言實現的方法如Win32 API函數。如前所是外部方法不能是抽象方法。我們看下面的一個例子:
using System;
using System.Runtime.InteropServices;
class MyClass
{
[DllImport("user32.dll")]
static extern int MessageBoxA(int hWnd, string msg,string caption, int type);
public static void Main()
{
MessageBoxA(0, "Hello, World!", "This is called from a C# app!", 0);
}
}
程序經編譯後執行
這裡我們調用了Win32 API函數int MessageBoxA(int hWnd, string msg,string caption, int type)。