一、泛型接口 核心语法
1. 定义格式
在接口名后加<T>,方法中直接使用泛型 T,方法后不需要加<T>
//泛型接口:支持任意类型做加减规则 internal interface Ical<T> { T Add(T a, T b); T Sub(T a, T b); }2. 解决的痛点
普通接口写死int Add(int a,int b)只能数字相加;
泛型接口适配所有类型:int、string、自定义类全部支持。
二、泛型接口的两种实现方式(必考重点)
方式1:普通类实现泛型接口(关闭泛型)
实现接口时直接指定具体类型,T 被固定死。
特点:一个类只服务一种固定类型
① Calc2 实现 int 类型接口
public class Calc2 : Ical<int> { public int Add(int a, int b) { return a + b; } public int Sub(int a, int b) { return a - b; } }② Calc3 实现 string 类型接口
public class Calc3 : Ical<string> { //字符串拼接 public string Add(string a, string b) { return a + b; } //自定义字符串减法:包含则替换 public string Sub(string a, string b) { if (a.Contains(b)) { return a.Replace(b, "x"); } return a; } }运行结果
Calc2: 10 + 20 = 30 10 - 20 = -10 Calc3: "a"+"a" = "aa" "a"-"a" = "x"方式2:泛型类实现泛型接口(保留泛型)
如果不想固定接口类型,由调用时动态决定类型:
必须在类名后也加<T>,让类的泛型传递给接口
// 类的T 决定 接口的T public class Calc1<T> : Ical<T> { public T Add(T a, T b) { // 不是所有类型都支持 +、- 运算符 return default(T); } public T Sub(T a, T b) { return default(T); } }核心规则(必背)
接口是泛型、类也想通用 →类必须也定义成泛型类
由对象实例化时 <类型>统一确定接口类型
无法运算类型,返回default(T)默认值
调用演示
// T = int Calc1<int> c = new Calc1<int>(); Console.WriteLine(c.Add(10, 20)); // int默认值 0 // T = string Calc1<string> c1 = new Calc1<string>(); Console.WriteLine(c1.Sub("ss", "sss")); // string默认值 null三、两种实现方式对比总结
实现方式 | 写法 | 特点 | 适用场景 |
|---|---|---|---|
普通类实现泛型接口 | Ical<具体类型> | 类型固定、逻辑可定制 | 不同类型有专属运算逻辑(int加减、字符串加减) |
泛型类实现泛型接口 | 类<T> : Ical<T> | 类型灵活、通用模板 | 统一逻辑、不区分具体类型 |
四、重点易错点
泛型接口接口名带T,方法不带T
普通类实现泛型接口 →必须写死具体类型
想要接口类型动态可变 →类必须也是泛型类
泛型 T 不能默认支持加减乘除运算,非数值类型返回
default(T)string没有减法运算符,可自定义业务减法逻辑(案例中替换字符)
五、完整运行输出结果
30 -10 x aa 0六、满分背诵口诀
泛型接口后面T,方法只用不用写
普通类实现定类型,专属逻辑自己整
泛型类实现传T,类型调用才确定
通用类型无运算,默认值来兜底整