香蕉视频app

香蕉视频appKeep on going never give up.

Let's Go

C# 學習筆記(42)接口

C#Lonely2019-05-18 00:15:1666次0條

什么是接口?

接口可以理解為對一組方法進行聲明進行的統一命名,但這些方法沒有提供任何的實現。香蕉视频app也就是說,把一組方法聲明在一個接口中,然后繼承于該接口的類都需要實現這些方法。

香蕉视频app 例如,很多類型(比如int類型、string類型和字符類型等)都需要比較大小,此時可以定義一個比較接口,在該接口的中定義比較方法,然后讓這些類型去繼承接口,并實現自己的比較方法。

通過接口,你可以對方法進行統一管理,避免了在每種類型中重復定義這些方法。

接口的定義

接口的定義與類的定義非常相似,只是使用的關鍵字不一樣罷了,類的定義使用class關鍵字,而接口使用interface香蕉视频app關鍵字進行定義。在Visual Studio中添加接口的步驟如下:右擊項目,在彈出的菜單中選擇“添加”--> “新建項”菜單項,在彈出的窗口中選擇“接口”并命名接口名稱,最后點擊添加按鈕,這樣就完成了接口的添加。

image.png


接口定義的語法:

[訪問修飾符] interface 接口名

{

//接口成員定義

}

下面這段代碼就是一個簡單接口的定義,它并沒有定義任何方法。

interface IFlyable
{

}

下面向該接口添加一個方法,以讓所有繼承該接口的類都可以實現這個方法,添加方法之后的代碼如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp
{

    /// <summary>
    /// 飛行接口
    /// </summary>
    interface IFlyable
    {
        //接口中的成員不能加訪問修飾符,默認為public,不能修改。
        void Fly(); //定義飛行方法,繼承該接口的類都要實現該方法       
    }
}

定義完接口之后,添加Bird、Aircraft、Meteor三個類來繼承接口,如果有類想要繼承該接口,則它必須實現接口中定義的所有方法。類繼承接口與繼承類是一樣的,只需要使用英文的冒號“:”,后接接口名稱就可以了。代碼如下所示:

/// <summary>
/// 鳥
/// </summary>
public class Bird : IFlyable //繼承接口
{
    public void Fly() //實現接口方法
    {
        Console.WriteLine("鳥能夠在天上飛");
    }
}

/// <summary>
/// 飛機
/// </summary>
public class Aircraft : IFlyable //繼承接口
{
    public void Fly() //實現接口方法
    {
        Console.WriteLine("飛機能夠在天上飛");
    }
}

/// <summary>
/// 風箏
/// </summary>
public class Kite: IFlyable //繼承接口
{
    public void Fly() //實現接口方法
    {
        Console.WriteLine("風箏能夠在天上飛");
    }
}

香蕉视频app 調用接口中的方法代碼如下所示:

IFlyable[] fly = { new Bird(), new Aircraft(), new Kite() };
for (int i = 0; i < fly.Length; i++)
{
    fly[i].Fly(); //調用接口中的方法
}
Console.ReadKey();

運行結果:

image.png

顯式接口實現方式

顯式接口實現指的是使用接口名作為方法名的前綴,這稱為“顯式接口實現”;傳統的實現方式,稱為“隱式接口實現”。

當多個接口中包含相同方法名稱、相同返回類型和相同參數時,如果一個類同時實現了這些接口,隱式接口實現就會出現命名沖突的問題,下面的代碼對比進行了演示。

/// <summary>
/// 中文接口
/// </summary>
interface IChinese
{
    void SayHello(); //打招呼
}

/// <summary>
/// 英文接口
/// </summary>
interface IEnglish
{
    void SayHello(); //打招呼
}

// 我會用中文打招呼也會用英文打招呼,實現了兩個接口
public class Me : IChinese, IEnglish
{
    //隱式接口實現
    public void SayHello()
    {
        Console.WriteLine("你好");
    }
}

香蕉视频app 以上代碼中定義了一個Me類,它實現了兩個接口,并且這兩個接口中聲明的方法具有相同的返回類型、相同的方法名稱和相同的參數(這里都沒有參數)。若采用隱式的接口實現方式,下面的代碼將調用相同的SayHello方法,而不管具體是獲取了哪個接口。

香蕉视频app 代碼示例:

//調用接口中的方法
//使用隱式接口實現的方法有兩種調用方法,即直接用類和接口都可以調用SayHello方法。

//方法一(使用類調用):
Me me = new Me();
me.SayHello();

//方法二(使用接口調用):
IChinese chinese = new Me();
chinese.SayHello();

IEnglish english = new Me();
english.SayHello();

Console.ReadKey();

香蕉视频app 運行結果:

image.png

香蕉视频app 從運行結果可以發現,不管獲得了哪個接口,程序都是調用的同一個方法實現,即都是輸出“你好”。但我們期望的結果并不是這樣,我們希望調用IChinese接口的SayHello方法可以輸出“你好”,而調用IEnglish接口的SayHello方法可以輸出“Hello”。

顯式的接口實現方法可以解決這樣的命名沖突問題,下面代碼演示顯式接口實現的方法。

代碼示例:

/// <summary>
/// 中文接口
/// </summary>
interface IChinese
{
    void SayHello(); //打招呼
}

/// <summary>
/// 英文接口
/// </summary>
interface IEnglish
{
    void SayHello(); //打招呼
}

// 我會用中文打招呼也會用英文打招呼,實現了兩個接口
public class Me : IChinese, IEnglish
{
    //顯式的接口實現
    void IChinese.SayHello() //不允許使用任何訪問修飾符,顯式實現的成員都默認為私有
    {
        Console.WriteLine("你好");
    }
    
    //顯式的接口實現
    void IEnglish.SayHello() //不允許使用任何訪問修飾符,顯式實現的成員都默認為私有
    {
        Console.WriteLine("Hello");
    }        
}

調用代碼:

//調用接口中的方法
//使用顯式接口實現的方法只能通過接口來調用SayHello方法,不能通過類來調用。
IChinese chinese = new Me();
chinese.SayHello();

IEnglish english = new Me();
english.SayHello();

Console.ReadKey();

運行結果:

image.png

由此可見,顯式的接口實現解決了命名沖突問題,程序根據不同接口輸出了不同的打招呼內容。

香蕉视频app 在使用顯式的接口實現方式時,需要注意以下幾個問題:

1、若顯式實現接口,方法中不能使用任何訪問修飾符,顯式實現的成員都默認為私有

2、顯式實現的成員默認是私有的,所以這些成員都不能通過類的對象進行訪問。


總結:

1、接口是指定一組函數成員而不實現它們的引用類型,這是是一種規范。

2、接口的定義使用interface香蕉视频app關鍵字,接口的名稱一般以I開頭able結尾,表示“我能做”的意思,例如微軟類庫中的IComparable接口、ICloneable接口等。

3、只能使用類和結構來實現接口,實現接口的子類必須實現該接口的全部成員。

4、為了多態,接口不能被實例化。也就是說,不能new接口(不能創建對象)。

5、接口中所有的成員都默認是公共的(即默認為public),因此不能接口中的成員不能加訪問修飾符如:public、private和protected等,也不能使用static修飾符。如果顯式地指定了訪問修飾符,則會出現編譯時錯誤。

香蕉视频app 6、接口中只能有方法、屬性、事件、索引器,接口中不能包含字段、運算符重載、實力構造函數、析構函數。如果在接口中定義了不該包含的成員,則會導致編譯錯誤。

7、接口中的成員不能有任何實現(即“光說不做”,只是定義了一組未實現的成員)。

8、接口與接口之間可以繼承,并且可以多繼承。接口并不能去繼承一個類,而類可以繼承接口(即接口只能繼承接口,而類既可以繼承接口,也可以繼承類)。

9、類是單繼承的,如果一個類即繼承了類又實現了接口,那么在語法上類必須寫在接口前面。例如:public class 子類:父類,接口,接口{ }

香蕉视频app 10、當一個抽象類繼承接口的時候,可以不實現接口中的方法,但是必須將其定義為公共的抽象方法,繼承該抽象類的子類必須實現抽象父類中的所有抽象方法。


顯式實現接口的目的:解決方法重名的問題。若顯式實現接口,方法中不能使用任何訪問修飾符,顯式實現的成員都默認為私有,所以這些成員都不能通過類的對象進行訪問。

隱式接口實現與顯式接口實現的區別:香蕉视频app使用隱式接口實現時,類和接口都可以訪問接口中的方法。使用顯式接口實現時,只能通過接口來訪問接口中的方法,因為此時接口方法默認為私有。

什么時候使用隱式接口實現?什么時候使用顯式接口實現?

當類實現單個接口時,通常使用隱式接口實現方法,這樣類的對象可以直接去訪問接口方法。

香蕉视频app 當類實現了多個接口,并且接口中包含相同的方法名稱、參數和返回類型時,則應該使用顯式接口實現方法。即使沒有相同的方法簽名,在實現多個接口時,仍推薦使用顯式的方式,因為這樣可以標識出哪個方法屬于哪個接口。顯式接口實現語法:返回類型 接口名.方法名()


接口與抽象類的區別?

1、抽象類使用abstract關鍵字進行定義,而接口使用interface香蕉视频app關鍵字進行定義,兩者都不能進行實例化。

2、抽象類中可以包含虛方法、非抽象成員和靜態成員,但接口中不能包含虛方法和任何靜態成員,并且接口中只能定義方法,不能有具體實現,方法的具體實現由實現類完成。

3、抽象類不能實現多繼承,接口則可以多繼承。注意,從嚴格意義上說,類繼承接口應該成為類實現接口。

4、抽象類是一類對象的抽象,繼承于抽象類的類與抽象類為屬于關系;而類實現接口只是代表實現類具有接口聲明的方法,是一種can-do關系。所以一般接口后都帶有able字段,表示“我能做”的意思。


暗錨,解決錨點偏移

文章評論

    嘿,來試試登錄吧!