程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#編程利器之三:接口(Interface)

C#編程利器之三:接口(Interface)

編輯:關於C#

C#接口是一個讓很多初學者容易迷糊的東西,用起來好象很簡單,定義接口,然後在裡面定義方法, 通過繼承與他的子類來完成具體的實現。但沒有真正認識接口的作用的時候就覺得用接口是多此一舉,當 然你這樣想是絕對錯誤的。在軟件設計中有一個非常重要的原則就是:面向接口編程,依賴與接口或抽象 層。可見接口在真正的開發中是多麼的重要。

在之前C#編程利器之一:類(Class)一文裡介紹了類的相關知識,本文主要介紹OO編程中的另一個重要 知識點--接口。在某種程度上說,接口也是類,一種特殊的類或抽象類。 更准確說接口只包含方法、委 托或事件的簽名。方法的實現是在實現接口的類中完成的[MSDN]。

一、接口的定義

如上MSDN上對接口的定義,接口只包含方法、委托或事件的簽名。這句話用更通俗點的解釋便是,接 口只是負責完成定義的操作,而不去實現具體的細節。如下面的IPlayer接口,它是一個玩游戲的接口, 裡面只是定義了相應的方法,而不帶方法的具體實現,代碼如下:

1/**//// <summary>
2/// 玩游戲接口
3/// </summary>
4public interface IPlayer
5{
6  /**//// <summary>
7  /// 獲取玩家的名字
8  /// </summary>
9  /// <returns>玩家的名字</returns>
10  string GetName();
11
12  /**//// <summary>
13  /// 由Player決定出什麼手勢
14  /// </summary>
15  /// <returns>本接口定義的三個常量之一</returns>
16  string Show();
17}

以上就是一個典型的接口的定義。定義了一個名為IPlayer的接口,內部定義了兩個方法GetName和 Show。除了在接口裡定義方法以外,我們還可以定義屬性、索引及事件等,詳細請查看MSDN上的定義或是 相關書籍,這裡以屬性為例簡單介紹下,在接口裡只能定義不實現,具體的實現是交給其子類去完成的, 那麼屬性應該怎麼定義呢?

通常我們定義屬性如下:

1/**//// <summary>
2/// 定義_Name屬性,並提供get;set屬性訪問器
3/// </summary>
4private string _Name;
5public string Name
6{
7  get { return _Name; }
8  set { _Name = value; }
9}

那麼在接口中又是怎麼定義屬性,並讓其子類去實現呢?如下代碼段:

1/**//// <summary>
2/// 定義接口,並在接口裡定義一名為Name的屬性
3/// </summary>
4public interface IAttribute
5{
6  string Name { get;set;}
7}
8/**//// <summary>
9/// 定義一個類去繼承IAttribute接口,並實現其屬性
10/// </summary>
11public class Component : IAttribute
12{
13  public string Name
14  {
15    get
16    {
17      return "張三";
18    }
19    set
20    {
21      this.Name = value;
22    }
23  }
24}

二、接口的實現

在本文開始部分曾經說過,接口只負責定義,不負責實現,具體的實現是交給他的子類去完成的。 OK ,現在我們就以上面定義的玩游戲的接口IPlayer為例,來簡單的介紹下接口的實現。

就拿我的趣味編程中的玩剪刀石頭布的案例來說吧,爺爺和奶奶從小就教授小孫子各中東西,其中玩 趣味游戲就他們常有的事,可小孫子還小不知道變換,每次都出剪刀,這樣能贏他爺爺嗎?有了這個分析 ,我們可以怎麼做呢?上面定義了接口,我們是不是直接去實現這個接口便OK了。爺爺和小孫子玩游戲, 那麼就定義兩個類去繼承IPlayer接口。代碼如下:

1/**//// <summary>
2/// 出手動作狀態
3/// </summary>
4public class Options
5{
6  public static readonly string JIANDAO = "剪刀";
7  public static readonly string SHITOU = "石頭";
8  public static readonly string BU = "布";
9}

游戲裡只會出現這三種動作狀態,所以我們可以進行封裝,這裡是通過類封裝的,當然我們也可以通 過別的相關技術來封裝,比如在本系列第二篇文章《C#編程利器之二:結構與枚舉(Structure and enumeration)》 裡介紹的結構與枚舉,本例中所出現的這三中不變的狀態完全可以使用結構或枚舉來封 裝,詳細請閱讀上篇文章。下面是定義爺爺(Grandpa)類和孫子(Grandson)類去實現接口(IPlayer) 了。代碼如下:

1/**//// <summary>
2/// 爺爺--玩家之一
3/// </summary>
4public class Grandpa:IPlayer
5{
6  public string GetName()
7  {
8    return "爺爺";
9  }
10
11  public string Show()
12  {
13    Random random = new Random();
14    int i = (int)(random.Next() * 1000) % 3;
15    switch (i)
16    {
17      case 0: return Options.JIANDAO;
18      case 1: return Options.SHITOU;
19      default: return Options.BU;
20    }
21  }
22}

1/**//// <summary>
2/// 孫子--玩家之一
3/// </summary>
4public class Grandson:IPlayer
5{
6  public string GetName()
7  {
8    return "孫子";
9  }
10
11  public string Show()
12  {
13    return Options.JIANDAO;
14  }
15}

如上,我們的GrandPa和GrandSon就實現了接口IPlayer,如下圖示:

三、接口的繼承

關於這點這裡就不作詳細的介紹,只需要記住有這樣一句話就萬歲了:“一個接口可從一個或多個基 接口繼承”。示意性代碼:

1interface IA { }
2interface IB:IA { }
3interface IC : IA, IB { }
4interface ID : IA, IB, IC { }

四、接口的特性

接口除了可以包含方法之外,還可以包含屬性、索引器、事件等,而且這些成員都被定義為公有的。 除此之外,不能包含任何其他的成員,例如:常量、域、構造函數、析構函數、靜態成員。一個類可以直 接繼承多個接口,但只能直接繼承一個類(包括抽象類)。

從類型上來說接口是引用類型的,類似於類,和抽象類的相似之處有三點:

1、不能實例化;

2、包含未實現的方法聲明;

3、派生類必須實現未實現的方法,抽象類是抽象方法,接口則是所有成員(不僅是方法包括其他成員 );

五、接口與回調

通常情況下,我們創建一個對象,並馬上直接去使用它的方法。然而,在有些情況下,希望能在某個 場景出現後或條件滿足時才調用此對象的方法。回調就可以解決這個“延遲調用對象方法”的問題。這個 被調用方法的對象稱為回調對象。

首先創建一個回調對象,然後再創建一個控制器對象,將回調對象需要被調用的方法告訴控制器對象.控 制器對象負責檢查某個場景是否出現或某個條件是否滿足.當此場景出現或此條件滿足時,自動調用回調對 象的方法.示意性代碼如下:

1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace CallBack
6{
7  class Program
8  {
9    static void Main(string[] args)
10    {
11      //創建一個控制器對象,將提供給它的回調對象傳入
12      Resolve resolve = new Resolve(new PlayBasketball());
13      resolve.Play();
14
15      resolve = new Resolve(new PlayFootball());
16      resolve.Play();
17    }
18  }
19
20  /**//// <summary>
21  /// 定義一個接口--回調對象
22  /// </summary>
23  public interface IPlayer
24  {
25    void Play();
26  }
27
28  /**//// <summary>
29  /// 籃球
30  /// </summary>
31  public class PlayBasketball:IPlayer
32  {
33    public void Play()
34    {
35      Console.WriteLine("玩籃球");
36    }
37  }
38
39  /**//// <summary>
40  /// 足球
41  /// </summary>
42  public class PlayFootball : IPlayer
43  {
44    public void Play()
45    {
46      Console.WriteLine("玩足球");
47    }
48  }
49
50  /**//// <summary>
51  /// 控制角色--控制器對象
52  /// </summary>
53  public class Resolve
54  {
55    //持有一個接口的引用,通過構造方法初始化
56    private IPlayer player;
57    public Resolve(IPlayer player)
58    {
59      this.player = player;
60    }
61
62    public void Play()
63    {
64      player.Play();
65    }
66  }
67}

關於接口的相關知識點本文就介紹於此,更詳細的學習接口這門功夫請大家查閱相關資料。

出處:http://beniao.cnblogs.com/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved