CLR設計類型之接口

寫在前面的話:            編程

        寫到這一節的時候,CLR設計類型就已經結束了,由於CLR要求的是有必定基礎的人看的,因此咱們不是從基礎類型以及運算符開始的,文章從一開始就講的是深刻面向對象編程,研究C#程序的設計模式。C#面向對象編程有三個特色:封裝,繼承,多態。接口的實現就是實現繼承設計模式

           其實在開始以前說一下這兩天發生的事情,前幾天維護項目代碼時,雖然是本身寫得可是因爲邏輯判斷比較多,有些變量名起的也不是頗有意義,在看的時候就徹底忘記當初爲啥要寫成這樣了,也是有點汗顏,因此最近就把代碼整潔之道也放在了看書的目錄上,從此的示例代碼也會符合代碼整潔之道上的一些要求去寫。而不是用無心義的a,b,c去作爲變量名。安全

接口定義:ide

         那麼接口要作的事,也是讓代碼更加簡潔的事情,接口定義了全部類繼承接口時應遵循的語法合同。接口定義了語法合同 "是什麼" 部分,派生類定義了語法合同 "怎麼作" 部分。接口定義了屬性、方法和事件,這些都是接口的成員。接口只包含了成員的聲明。成員的定義是派生類的責任。接口提供了派生類應遵循的標準結構。ui

        說了這麼多,那麼咱們用接口實現一個計算器的例子,經過這個例子來講明接口究竟是如何定義,如何使用的。先看接口的定義:spa

 1   interface ICalculator {
 2         //一般接口命令以 I 字母開頭,ICalculator 中文意思就是計算器接口
 3         //這個接口規定了一個計算器要有基本的加減乘除運算方法
 4         //加法
 5         int Add(int x,int y);
 6         //減法
 7         int Reduce(int x, int y);
 8         //乘法
 9         int Ride(int x, int y);
10         //除法
11         int Except(int x, int y);
12     }
View Code

接口實現:設計

      上面的代碼很簡單吧,在接口中不能聲明靜態方法,接口中的方法不能用可見性修飾符修飾,在來看這句話:接口定義了全部類繼承接口時應遵循的語法合同,也就是接口先規定好了我要實現那些方法和行爲,繼承個人要實現(重寫)個人全部方法,而且返回值要和我相同,參數也要和我相同。不然就是違反了合同,語法就會報出錯誤。有了合同,類如今就像是一個建築包工頭,我只須要按照你的約定作,你讓我蓋十層樓,我就蓋十層樓。繼承接口類以下:code

 1  public class Calculator : ICalculator
 2     {
 3         //:表示繼承了計算機接口
 4         //實現接口中的加法
 5         public int Add(int x, int y) {
 6             int sum = x + y;
 7             return sum;
 8         }
 9         //實現接口中的減法
10         public int Reduce(int x, int y)
11         {
12             int sum = x - y;
13             return sum;
14         }
15         //實現接口中的乘法
16         public int Ride(int x, int y)
17         {
18             int sum = x * y;
19             return sum;
20         }
21         //實現接口中的除法
22         public int Except(int x, int y)
23         {
24             int sum = x / y;
25             return sum;
26         }
27     }
View Code

接口調用: orm

    繼承類必須實現接口中的全部方法,而且不能靜態類繼承接口,這裏實現了接口中得全部方法,繼續用上一個例子,接口比如是一個承包方:會告訴你我要什麼樣的房子,房子的顏色和大小,繼承類就是施工方,按照承包方的要求去蓋房子,知道了房子大小就開始計算要買多少磚瓦水泥。那麼實現了接口的類如何調用實現呢?和正常的類同樣調用和實現:對象

1     static void Main(string[] args)
2         {
3             //實例化一個計算器
4             Calculator calculator1 = new Calculator();
5             //輸出計算器的實現  輸出結果爲3
6             Console.WriteLine(calculator1.Reduce(5, 2));
7         }
View Code

        這就是一個最簡單的接口調用和實現。看了這麼多,你可能以爲使用接口不是更加麻煩了麼?若是從基類中繼承不是更加簡單?這樣還須要定義接口,而且接口中全部成員都必須實現其方法。代表上來看是這樣的,那麼全部東西都有其使用的場景,接口的出生也不是爲了簡單類而出生。C#和CLR所支持的泛型接口爲開發人員提供了許多很是出色的功能,接下來咱們討論一下泛型接口提供的一些好處

泛型接口

        首先泛型接口提供了出色的編譯時類型安全性,有的接口在定義的方法使用了object參數或object返回類型,在代碼調用這些接口方法時,可傳遞任何類型的實例應用,但這一般不是咱們指望的,而且使用非泛型還會形成裝箱拆箱操做,今天列舉C#中另一個泛型接口IComparable,

 1   public interface IComparable<in T>
 2     {
 3         //
 4         // 摘要:
 5         //     比較當前對象和同一類型的另外一對象。
 6         //
 7         // 參數:
 8         //   other:
 9         //     與此對象進行比較的對象。
10         //
11         // 返回結果:
12         //     一個值,指示要比較的對象的相對順序。返回值的含義以下:值含義小於零此對象小於 other 參數。零此對象等於 other。大於零此對象大於 other。
13         int CompareTo(T other);
14     }
View Code

       這是進行大小比較的接口,接受的參數是泛型,而且泛型參數支持協變和逆變,更大程度的支持參數的靈活性,他展現了泛型接口的另一個好處,類能夠實現一個接口若干次,只要每次使用不一樣的類型參數,示例:

 1   public sealed class Comparable:IComparable<int>,IComparable<string>
 2     {
 3         private  int  m_val=5;
 4         //方法實現了IComparable<string>的CompareTo方法
 5         public int CompareTo(string str)
 6         {
 7             return m_val.CompareTo(Convert.ToInt32(str));
 8         }
 9         //方法實現了IComparable<string>的CompareTo方法
10         public int CompareTo(int number)
11         {
12             return m_val.CompareTo(number);
13         }
14     }
View Code

      須要說明的是,上面的代碼最終在return m_val.CompareTo(Convert.ToInt32(str));這裏實際調用的元數據int的CompareTo方法,所以雖然能夠接收不一樣類型參數,但在比較的時候仍是要對泛型參數進行int轉化,才能夠實現int的CompareTo方法。

泛型接口約束

          泛型接口還能夠對自身進行約束,也稱做接口約束,接口約束能夠將泛型類型參數約束爲多個接口,這樣一來,傳遞的參數類型必須所有接口約束。初讀這段話是否是很暈?什麼是將泛型類型參數約束爲多個接口?爲何約束事後,傳遞的參數類型必須實現所有約束?所有約束指的是哪一些約束?

 1    public static class SomeType {
 2         private static void Test() {
 3             int x = 6;
 4             Guid g = new Guid();
 5             //能夠經過 由於int繼承了IComparable, IFormattable, IConvertible, IComparable<Int32>, IEquatable<Int32>
 6             M(x);
 7             //編譯不能經過,由於GUID沒有繼承IConvertible
 8             //public struct Guid : IFormattable, IComparable, IComparable<Guid>, IEquatable<Guid>
 9             M(g);
10         }
11         //M的類型參數T被約束爲只支持同時實現了
12         //IComparable和IConvertible接口的類型
13         private static int M<T>(T t) where T : IComparable, IConvertible {
14             return 1;
15         }
16     }
View Code

      上面的方法,就是將參數約束了指定的接口,而且只有實現被約束的接口才能經過編譯,不然就會失敗。這就是接口的泛型約束。

總結:類仍是接口?

             首先類只能繼承一個實現,而接口能夠繼承多個,若是多種對象類型都能作某事,就爲它建立接口。

             若是是簡單的類型,那麼就使用基類,基類實現了大量的功能,而且不用實現全部成員

相關文章
相關標籤/搜索