$9 泛型基础
主要内容 为何使用泛型 创建泛型类 泛型和继承
为何使用泛型 public class IntStack { int[] items = new int[100]; int current = 0; public void Push(int x) { items[current++] = x; } public int Pop() { return items[--current]; } } public static void Main() { IntStack st = new IntStack(); for(int i=1; i<=10; i++) st.Push(i); int x = st.Pop(); }
为何使用泛型 public class StringStack { string[] items = new string[100]; int current = 0; public void Push(string x) { items[current++] = x; } public string Pop() { return items[--current]; } } public static void Main() { StringStack st = new StringStack(); for(int i=1; i<=10; i++) st.Push(new string(‘a’,i)); string y = st.Pop(); }
为何使用泛型 public class DoubleStack { //…… } public class DateTimeStack public class Student {//...}; public class StudentStack
为何使用泛型 public class ObjStack { object[] items = new object[100]; int current = 0; public void Push(object x) { items[current++] = x; } public object Pop() { return items[--current]; } }
为何使用泛型 性能损失 装箱 拆箱 ObjStack int int Object Object public static void Main() { ObjStack st = new ObjStack(); for(int i=1; i<=10; i++) st.Push(i); int x = (int)st.Pop(); } int int 装箱 拆箱 Object Object ObjStack 性能损失
为何使用泛型 × 通过编译,但运行时出错! 拆箱 ObjStack int int string Object Object Object public static void Main() { ObjStack st = new ObjStack(); for(int i=1; i<=10; i++) st.Push(i); int x = (int)st.Pop(); string y = (string)st.Pop(); } int int string × 拆箱 Object Object Object ObjStack 通过编译,但运行时出错!
为何使用泛型 public class Stack<T> { T[] items = new T[100]; int current = 0; public void Push(T x) { items[current++] = x; } public T Pop() { return items[--current]; } }
为何使用泛型 × 在编译时检查出错误 ObjStack int int string public static void Main() { Stack<int> st = new Stack<int>(); for(int i=1; i<=10; i++) st.Push(i); int x = (int)st.Pop(); string y = (string)st.Pop(); } × int int string ObjStack 在编译时检查出错误
为何使用泛型 泛型的优越性 更高层次上的抽象性 对算法和数据结构更强的表达能力 更为方便的复用:参数替换 类型安全性:无需装箱/拆箱 不损害程序性能而实现更高的灵活性
创建泛型类
创建泛型类 泛型类(Generic class) 声明:modifier class ClassName <T1, T2, T3 …> public class Stack<T>
创建泛型类 泛型类(Generic class) 声明:modifier class ClassName <T1, T2, T3 …> 创建:abstract type concrete type public class Stack<T> Stack<int> st = new Stack<int>();
创建泛型类 泛型类(Generic class) 使用具体类型 使用类型参数 字段类型 方法参数类型 方法返回类型 public class Stack<T> { T[] items = new T[100]; int current = 0; public void Push(T x) { items[current++] = x; } public T Pop() { return items[--current]; } }
创建泛型类 泛型类(Generic class) 使用类型参数(续) 方法中局部变量类型 构造函数定义中不出现类型参数! public class Stack<T> { public T Peek() { T t = items[current]; return t; } public Stack() {} public Stack(int size) { items = new T[size]; } }
创建泛型类 类型限制 主要限制 public class Stack<T> where T: struct public class Queue<T> where T: class public class Dictionary<K,D> where K: struct where D: class
创建泛型类 类型限制 主要限制 次要限制 接口限制 public class PriQueue<T> where T: IComparable { public void Push(T x) for(int i=0; i<items.length; i++) if(x.CompareTo(items[i]) >= 0) //... }
创建泛型类 × 类型限制 主要限制 次要限制 接口限制 基类限制 public class Student {} public class Undergraduate: Student {} public class Graduate: Student public class PriQueue<T> where T: Student PriQueue<Student> q1 = new PriQueue<Student>(); PriQueue<Graduate> q2 = new PriQueue<Graduate>(); PriQueue<string> q3 = PriQueue<string>(); ×
创建泛型类 类型限制 主要限制 次要限制 接口限制 基类限制 构造函数限制 public class Student { public Student() {} } public class Queue<T> where T: Student, new() { T[] items; public Queue(int size) items = new T[size]; for(int i=0; i<size; i++) items[i] = new T(); }