public class Stack { PRivate int[] m_item; public int Pop(){...} public void Push(int item){...} public Stack(int i) { this.m_item = new int[i]; } } 上面代碼運行的很好,但是,當我們需要一個棧來保存string類型時,該怎么辦呢?很多人都會想到把上面的代碼復制一份,把int改成string不就行了。當然,這樣做本身是沒有任何問題的,但一個優秀的程序是不會這樣做的,因為他想到若以后再需要long、Node類型的棧該怎樣做呢?還要再復制嗎?優秀的程序員會想到用一個通用的數據類型object來實現這個棧:
public class Stack { private object[] m_item; public object Pop(){...} public void Push(object item){...} public Stack(int i) { this.m_item = new[i]; } } 這個棧寫的不錯,他非常靈活,可以接收任何數據類型,可以說是一勞永逸。但全面地講,也不是沒有缺陷的,主要表現在:
Node1 x = new Node1(); stack.Push(x); Node2 y = (Node2)stack.Pop(); 上面的代碼在編譯時是完全沒問題的,但由于Push了一個Node1類型的數據,但在Pop時卻要求轉換為Node2類型,這將出現程序運行時的類型轉換異常,但卻逃離了編譯器的檢查。
public class Stack { private T[] m_item; public T Pop(){...} public void Push(T item){...} public Stack(int i) { this.m_item = new T[i]; } } 類的寫法不變,只是引入了通用數據類型T就可以適用于任何數據類型,并且類型安全的。這個類的調用方法:
//實例化只能保存int類型的類 Stack a = new Stack(100); a.Push(10); a.Push("8888"); //這一行編譯不通過,因為類a只接收int類型的數據 int x = a.Pop(); //實例化只能保存string類型的類 Stack b = new Stack(100); b.Push(10); //這一行編譯不通過,因為類b只接收string類型的數據 b.Push("8888"); string y = b.Pop(); 這個類和object實現的類有截然不同的區別: