接口的出現,是為了解決C#中不允許多重繼承的問題。
1、什麼是接口?
我覺得可以把接口理解為對一組方法聲明進行的統一命名,但這些方法沒有提供任何實現。
通過接口,就可以對方法進行統一管理,避免了在每種類型中重復定義這些方法。
2、如何使用接口來編程
2.1 接口的定義
interface ICustomCompare
{
//定義比較方法,繼承該接口的類都要實現該方法
int CompareTo(object other);
}
在接口中定義方法不能添加任何訪問修飾符,因為接口中的方法默認是public,如果顯示地指定了修飾符,則會出現編譯時錯誤。也不能使用static關鍵字進行修飾。
在接口中除了可以定義方法外,還可以包含屬性、事件、索引器,或者這4類成員(包括方法)類型的任意組合;但接口類型不能包含字段、運算符重載、實例構造函數和析構函數。
2.2 繼承接口
public class Person:ICustomCompare
{
int age;
public int Age{get{return age;} set{age=value;}}
//實現接口方法
public int CompareTo(object value)
{
if(value==null)
{
return 1;
}
//將Object類型強制轉換為Person類型
Person otherp=(Person)value;
//把當前對象的Age屬性與需要比較的對象的Age屬性進行對比
if(this.Age<otherp.Age)
{
return -1;
}
if(this.Age>otherp.Age)
{
return 1;
}
return 0;
}
}
在上面的的Person類中,實現了ICustomCompare接口中的CompareTo方法。
CompareTo方法會首先判斷參數對象是否為null,如果為null,則直接返回1,代表當前對象比傳入對象大。
如果對象不為空的話,強制轉換成Person類型,對Age屬性進行對比,當前對象的Age屬性值比傳入對象的Age屬性值大,則返回1,如果返回-1,則說明當前對象的Age屬性比傳入的對象小。
2.3 調用接口中的方法
class Program
{
static void Main(string[] args)
{
Person p1=new Person();
p1.Age=18;
Person p2=new Person();
p2.Age=19;
//調用接口中方法,對p1和p2進行比較
if(p1.CompareTo(p2)>0)
{
Console.WriteLine("p1比p2大");
}
else if(p1.CompareTo(p2)<0)
{
Console.WriteLine("p1比p2小");
}
else
{
Console.WriteLine("p1比p2一樣大");
}
Console.ReadKey();
}
}
3、顯示接口實現方法
在上面的示例代碼當中,使用了隱式的接口實現方式,即在實現代碼中沒有指定實現哪個接口中的CompareTo方法。
當然,也存在顯式的接口實現方式,在類實現接口的過程中,明確指出實現哪一個接口中的哪一個方法。
interface IChineseGreeting
{
//方法聲明
void SayHello();
}
interface IAmericanGreeting
{
//方法聲明
void SayHello();
}
//Speaker類實現了兩個接口
public class Speaker:IChineseGreeting,IAmericanGreeting
{
//隱式接口實現
public void SayHello()
{
Console.WriteLine("你好");
}
}
上面的Speaker類實現了兩個接口,碰巧兩個接口中聲明的方法具有相同的返回類型、相同的方法名稱和相同的參數。若采用隱式的接口實現方式,下面的代碼將調用相同的SayHello方法。
static void Main(string[] args)
{
Speaker speaker=new Speaker();
//調用中國人打招呼方法
IChineseGreeting chinese=(IChineseGreeting)speaker;
chinese.SayHello();
//調用美國人招呼方法
IAmericanGreeting American=(IAmericanGreeting)speaker;
American.SayHello();
}
當Main函數執行的時候,得到的接口是兩個 “你好”;
這並不是我們期望的結果,所以這種情況下,我們必須使用顯式的接口實現方式來解決這個命名沖突問題。
//Speaker類實現了兩個接口
public class Speaker:IChineseGreeting,IAmericanGreeting
{
//顯式接口實現
void IChineseGreeting.SayHello()
{
Console.WriteLine("你好");
}
//顯式接口實現
void IAmericanGreeting.SayHello()
{
Console.WriteLine("Hello");
}
}
使用這種方式就可以解決命名沖突問題。在使用顯示的接口山西ian方式時,需要注意一下幾個問題:
針對以上的兩種方式:顯式實現和隱式實現,下面針對兩種實現的區別和使用場景進行總結:
4、接口與抽象類
這裡主要是闡述一下兩者的區別:
上面的幾點只是接口與抽象類之間差異的主要方法,它們還有很多的不同,大家可以參考一下別的書籍或者別的博客。