1.介面的宣告
介面的宣告不能包含:資料成員,靜態變數;只能包含如下型別的靜態成員函式的宣告:方法,屬性,事件,索引器。宣告中不能包含任何實現的程式碼,而在每個成員成名的主體後,必須使用分號。
介面宣告可以有任何的修飾符public、protect、internl或private。
介面的成員是隱式的public,不允許任何訪問修飾符,包括public。
Public Interface IMyInterface
{
//介面成員是隱式的public,並且只有宣告
int Method1(int nVar1,int nVar2) ;
}
2.介面的實現
只有類和結構體才能實現介面,並且必須在基類列表中包括介面名稱;使用介面的類或結構需要為介面的每一個成員提供實現。
Class MyClass:IMyInterface
{
//在進行隱式的實現介面成員的時候,訪問修飾符要設為public
public int Method(int a,int b)
{
Console.WriteLine("{0}",a+b);
return a+b;
}
}
如果一個類即繼承了基類,又實現了介面,那麼在這個類的基類列表中的基類名稱必須放在所有的介面的前面。並且一個類只能有一個基類,列出的其他型別必須都是介面名。
介面不僅僅是類或結構要實現的成員列表,它是一個引用型別,我們不能直接通過類物件的成員訪問介面,然而我們可以通過把類物件引用強制轉換為介面型別來獲取指向介面的引用。這樣我們就可以使用點號來呼叫介面的方法了。這裡轉換推薦用as進行轉換。
Static void Main(string[] args)
{
int a = ;
int b = ;
MyClass mc = new MyClass();
//呼叫類物件的實現方法
mc.Method(a,b);
//將型別轉化為介面型別
IMyInterface mif = mc as IMyInterface;
mif.Method(a,b);
}
輸出結果:13
13
利用as進行強制轉換的好處:如果類實現了介面就會返回介面的引用(平安無事)如果類沒有實現介面就會丟擲異常,方便及時的發現錯誤。
3.實現多個介面
類或結構可以實現任意數量的介面。
所有實現的介面必須列在基類列表中且以逗號分隔。
如果一個類實現的兩個介面當中有重複的成員(具有相同的簽名和相同的返回型別),那麼在該類實現介面成員的時候,實現一次就可以滿足所有包含重複成員的介面。
interface interface1 { void Method(int a ,int b);}
interface interface2 { void Method(int a, int b);}
//實現多個介面用逗號相隔
public class MyClass : interface1, interface2
{
/*
* 如果兩個介面成員函式的返回型別和引數一致,
* 那麼進行一次實現就可以了
*/
public void Method(int a, int b)
{
Console.WriteLine("{0}", a + b);
}
}
如果想刻意的分離這兩個介面的介面成員,就需要建立顯式的介面成員成員實現。格式:介面名稱+點分隔符+介面的成員函式。注意:在顯示的呼叫介面成員的時候,已經預設為public,不能再新增訪問修飾符了。
interface interface1 { void Method(int a ,int b);}
interface interface2 { void Method(int a, int b);}
//實現多個介面用逗號相隔
public class MyClass : interface1, interface2
{
//顯示的實現interface1的介面成員
//已經預設為public,不能新增訪問修飾符了
void interface1.Method(int a, int b)
{
Console.WriteLine("{0}", a + b);
}
void interface2.Method(int a, int b)
{
Console.WriteLine("{0}", a + b);
}
}
但是這樣就只有顯式介面成員的實現,而沒有類級別的實現,所以在例項化該類的物件後,是無法點出該方法的。如果有顯式介面成員實現,類級別的實現是允許的,但是不是必須的。並且顯式介面成員實現智慧通過指向介面的引用來訪問,即使是類當中的成員函式來對介面成員進行訪問。
如果一個類實現了介面,那麼它的子類也會繼承其基類實現的介面成員,無需再次實現。
4.介面的繼承
要指定某個介面繼承其他介面,應在介面宣告中把介面以逗號分隔的列表形式放在介面名稱之後。和類的繼承格式相同。但是又與類不同,一個介面可以繼承任意多個介面,可以進行多重繼承。子介面除了包含自己宣告的介面之外還包括所有父介面的所有介面成員。
5.程式碼Demo
namespace ConsoleApplication2
{
interface ILoveWorld { void SayHello();}
class Creature{} //基類和介面同時實現的時候,基類要放在最前面
class Person : Creature,ILoveWorld
{
//隱式的宣告介面,既可以被類的物件訪問,又可以轉換為介面引用物件訪問
void SayHello()
{
Console.WriteLine("Hello World!");
}
//顯式的宣告介面成員,只能轉換為介面引用物件來訪問
void ILoveWorld.SayHello()
{
Console.WriteLine("Hello World!");
}
}
class Cat : Creature, ILoveWorld
{
//相對於顯式的介面實現方式。類級別的介面實現不是必須的。
void ILoveWorld.SayHello()
{
Console.WriteLine("MiaoMiaoMiao");
}
}
class Dog : Creature, ILoveWorld
{
//在顯式呼叫介面成員的時候不能用public
void ILoveWorld.SayHello()
{
Console.WriteLine("WangWangWang");
}
}
class Program
{
static void Main(string[] args)
{
//宣告一個Creature的陣列
Creature[] pCreatureArray = new Creature[];
//這裡用到了上次學的面向物件的IS-A的關係
pCreatureArray[] = new Person();
pCreatureArray[] = new Cat();
pCreatureArray[] = new Dog();
foreach (var creature in pCreatureArray)
{
//利用as進行轉換
ILoveWorld b = creature as ILoveWorld;
b.SayHello();
}
Console.ReadKey();
}
}
}
介面Demo
執行結果: