《C#图解教程》读书笔记之六:接口和转换
本篇已收錄至《C#圖解教程》讀書筆記目錄貼,點擊訪問該目錄可獲取更多內容。
一、接口那點事兒
(1)什么是接口?
一組函數(shù)成員而未實現(xiàn)的引用類型。只有類和結構能實現(xiàn)接口。
(2)從IComparable接口看接口實例:
假設有如下一段代碼,它使用Array類的一個靜態(tài)方法Sort對一個未排序的int類型數(shù)組進行排序,并輸出排序后的結果。
using System;class Program {static void Main(){var myInt = new[] { 20, 4, 16, 9, 2 }; // Create an array of ints. Array.Sort( myInt ); // Sort elements by magnitude.foreach ( var i in myInt ) // Print them out.Console.Write( "{0} ", i );} }Sort方法在int類型數(shù)組的排序工作上做的很好,但是如果我們嘗試在自定義的類上使用就會發(fā)生異常,例如下面的MyClass類。
class MyClass {public int TheValue; }Sort為何不能對MyClass進行排序,原因在于:它不知道如何比較自定義對象及如何進行排序。Array類的Sort方法其實依賴于一個IComparable的接口,它聲明在BCL中,包含唯一的CompareTo方法。它接收一個object類型的參數(shù),可以匹配任何引用類型。
public interface IComparable {int CompareTo(object obj); }這下,我們知道了int類型默認實現(xiàn)了IComparable接口,而我們的MyClass則沒有。因此,我們需要將MyClass實現(xiàn)這個IComparable接口。
class MyClass : IComparable {public int TheValue;public int CompareTo( object obj ) {MyClass mc = (MyClass) obj;if ( this.TheValue < mc.TheValue )return -1;if ( this.TheValue > mc.TheValue )return 1;return 0;} }現(xiàn)在,MyClass類實現(xiàn)了IComparable接口,它可以用于Sort方法了。
class Program {static void PrintOut( string s, MyClass[] mc ){Console.Write( s );foreach ( var m in mc )Console.Write( "{0} ", m.TheValue );Console.WriteLine( "" );}static void Main(){var myInt = new[] { 20, 4, 16, 9, 2 };MyClass[] mcArr = new MyClass[5]; for ( int i = 0; i < 5; i++ ) {mcArr[i] = new MyClass();mcArr[i].TheValue = myInt[i];}PrintOut( "Initial Order: ", mcArr ); Array.Sort( mcArr ); PrintOut( "Sorted Order: ", mcArr ); } }現(xiàn)在,一個完整的接口實例已經(jīng)完畢。
(3)使用接口注意事項:
①聲明接口時:不能包含:數(shù)據(jù)成員、靜態(tài)成員;只能聲明:方法、屬性、事件、索引器;
TIP:接口允許有任何的訪問修飾符,但是接口成員是隱式public的,不允許有任何的訪問修飾符,包括public。
②實現(xiàn)接口時:在基類列表中包括接口名稱;為每一個接口的成員實現(xiàn)接口;
(4)接口是一種引用類型:我們不能直接通過類或對象的成員訪問接口,然而,我們可以通過把類對象轉換成接口類型來獲取指向接口的引用。一旦有了接口的引用,我們就可以使用點號來調用接口的方法。
using System;interface IIfc1 {void PrintOut( string s ); }class MyClass : IIfc1 {public void PrintOut( string s ){Console.WriteLine( "Calling through: {0}", s );} }class Program {static void Main(){MyClass mc = new MyClass(); mc.PrintOut( "object" ); IIfc1 ifc = (IIfc1) mc; ifc.PrintOut( "interface" ); } }下面我們看看上面的代碼在內存中的分配:
(5)接口和as運算符=>天生一對
在以往使用接口引用時,我們往往會使用強制類型轉換,但強制類型轉換會拋出異常(異常是指代碼中的意外錯誤,它會嚴重降低代碼速度)。如何避免這個問題,我們可以使用as運算符,在類對象未實現(xiàn)接口時不會拋出異常,只會返回null。
二、看我72變:轉換
(1)本質:接受一個類型的值并使用它作為另一個類型的等價值的過程;
(2)轉換分類:
①預定義的轉換:數(shù)字、裝箱/拆箱、引用轉換;
數(shù)字類型的轉換詳見下圖:
裝箱/拆箱是一個比較重要的點,現(xiàn)在我們來看看:
裝箱(boxing)是值類型->引用類型,本質其實是創(chuàng)建副本。裝箱是一種隱式轉換,它接收值類型的值,根據(jù)這個值在在堆上創(chuàng)建一個完整的引用類型對象并返回對象引用。
拆箱(unboxing)是引用類型->值類型,本質把裝箱后的對象轉換回值類型。拆箱是顯示轉換。
②用戶自定義的轉換:隱式和顯示的自定義轉換;
using System;class Person {public string Name;public int Age;public Person( string name, int age ){Name = name;Age = age;}public static implicit operator int( Person p ) {return p.Age;}public static implicit operator Person( int i ) {return new Person( "Nemo", i ); } }class Program {static void Main(){Person bill = new Person( "bill", 25 );int age = bill;Console.WriteLine( "Person Info: {0}, {1}", bill.Name, age );Person anon = 35;Console.WriteLine( "Person Info: {0}, {1}", anon.Name, anon.Age );} } View Code(3)is運算符:
在轉換過程中,有些轉換是不成功的,并且會在運行時拋出一個InvalidCastException異常。我們可以使用is運算符來檢查轉換是否會成功,從而避免盲目地嘗試轉換。
本章思維導圖
附件
思維導圖(jpg、pdf以及mmap源文件)下載:http://pan.baidu.com/s/1qWNOGGW
?
作者:周旭龍
出處:http://www.cnblogs.com/edisonchou/
本文版權歸作者和博客園共有,歡迎轉載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
轉載于:https://www.cnblogs.com/edisonchou/p/3705240.html
總結
以上是生活随笔為你收集整理的《C#图解教程》读书笔记之六:接口和转换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: step3 . day5 数据结构之线性
- 下一篇: C# 汉字转拼音(全拼)