淺談C#中的介面

來源:互聯網
上載者:User

介面的相關陳述

  1. 一個介面定義了一個契約。
  2. 介面可以包容方法、C# 屬性、事件、以及索引器。
  3. 在一個介面聲明中,我們可以聲明零個或者多個成員。
  4. 所有介面成員的預設訪問類型都是 public。
  5. 如果在介面成員聲明中包括了任何修飾符,那麼會產生一個編譯器錯誤。
  6. 與一個非抽象類別類似,一個抽象類別必須提供介面中所有成員的實現,只要這些成員在這個類的基類中出現過。

介面的理解

面向介面編程利用 OO 的一個基本性質——多態,相同方法不同表現。可以這樣想一下,client 編寫自己程式的時候,如果直接面向一個具體類寫程式,那這個程式有個風吹草動的,那 client 就要受到影響,但如果面向一個介面就不同了,某個具體類變了,只知介面,不知具體類的 client 就可以完全不動。 都說上層領導比較好當,因為可以乾的事通常對老百姓來說是虛的,越虛就越不容易錯。

這個道理在 OO 中也是適用的。

換個視角看,面向介面編程反映 OO 的另一個方面——封裝,介面將具體實現封裝了起來,可以不影響客戶的情況下切換實現

介面的作用,一言以蔽之,就是標誌類的類別(type of class)。把不同類型的類歸於不同的介面,可以更好的管理他們。OO 的精髓,我以為,是對對象的抽象,最能體現這一點的就是介面。為什麼我們討論設計模式都只針對具備了抽象能力的語言(比如 c++、java、c# 等),就是因為設計模式所研究的,實際上就是如何合理的去抽象。(cowboy 的名言是“抽象就是抽去像的部分”,看似調侃,實乃至理)。

空介面的使用

在介面使用的時候,空介面有 2 種情況:

1.類似於 ObjectBuilder 中的 IBuilderPolicy,他們往往是做一個標記,表示需要某個功能。當然你也可以這麼用,來表示你的類具有某個功能,實現了你的某個介面。

namespace Microsoft.Practices.ObjectBuilder
{
     /// <summary>
     /// Represents a builder policy interface. Since there are no fixed requirements
     /// for policies, it acts as a marker interface from which to derive all other
     /// policy interfaces.
     /// </summary>
     public interface IBuilderPolicy
     {
     }
}

2.你的介面繼承了別的介面(非空),你的介面本身沒有聲明函數。這種情況一般是你不希望使用者使用父介面作為參數類型,因為他們的用途可能不同,此時就可以用空介面來實現。

interface Text
{
    string getText();
}
 
interface SqlText : Text
{
 
}

可以看到,Text 介面是用於返回一個字串。而 SqlText 是一個空介面,它繼承了 Text 介面。也就是說 SqlText 也是一種 Text。但是我們可以知道,任何一個字串不一定是 Sql 字串,所以此時聲明了一個 SqlText 介面來用於表名當前的字串是一個 Sql 字串。你的函數可以這樣聲明:

public void doQuery(SqlText sqlText)

而不是這樣:

public void doQuery(Text text)

避免使用者產生歧義的想法,一眼看去,就明白應該傳入一個 Sql 字串。

介面的成員為什麼沒有委託

我們都知道 C# 的介面是可以包含事件的,其實當我們看到事件的時候,很容易就會想到委託,委託是事件的基礎,如果對委託和事件不是特別清楚的程式員就一定不會明白,為什麼 C# 介面中可以包含事件而不能有委託呢。其實簡單的說法就是委託也是類型,delegate 關鍵字引入的是一個新的類型,所以一個 C# 介面無法包容一個委託並把它當作成員;而 event 關鍵字引入的是一個新的成員,因此事件可以歸人介面。理解這點,我們要從 C# 介面的使命說起,C# 介面是一個契約,規範了介面實現者的行為,而不是要有些什麼。很簡單,例如“黨員”是個介面,它肯定有個動作是“為人民服務”,“某某黨員”實現了“黨員”這個介面,那麼“某某黨員”肯定也要“為人民服務”,至於你“某某黨員”是否必須擁用“電腦”、“小孩”。那麼“黨員”這個介面中肯定不會有規定。這也就是介面的目的,規範了實現者的一些行為。所以 C# 介面的成員都是方法,不會有其它了。稍有 C# 常識的程式員都明白,C# 中的屬性,其實就是兩個方法,一個 Set 方法,一個 Get 方法,同樣事件和索引器也都是方法,請看下面的介面:

public interface IDrawingObject
{
    event EventHandler OnDraw;
   
    string Name
    {
        get;
        set;
    }
   
    int this[int index]
    {
        get;
        set;
    }
   
    void SetValue();
}

該介面包含了 C# 介面所能接納的所有成員,事件,屬性,索引器,方法。把該介面編譯後,我們用 MSIL Disassembler 工具查看一下:

這下大家都明白了,其實屬性 Name 對應於 Get_Name()、Set_Name() 這兩個方法,事件 OnDraw 對應於 add_OnDraw()、remove_OnDraw() 這兩個方法,索引器對應於 get_Item()、set_Item() 這兩個方法。在看下面的委託和類的定義:

public delegate void TestEventDelegate(object sender, System.EventArgs e);
class TestClass
{
    public void SetValue()
    {
    }
}

看到了吧,定義一個委託和定義一個類是沒有什麼區別的,都是定義了個新的類型。所以 C# 介面是不能有委託的,除非微軟告訴我們 C# 介面中是可以定義類的。
轉自:http://www.cftea.com/c/2009/02/83HTWD161NBEMFRS.asp

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.