接口
·
接口的定义
// interface 关键字,定义一个接口
interface USB
{
void Read(string[] datas);
}
接口的属性
- 是借口的任何类或结构必须实现其所有成员的方法
- 接口不能直接实例化,但是可以通过子类间接实例化
- 接口可以包含方法和属性的声明,但不能包含字段
- 接口中所有方法、属性默认public,不能再后面再添加修饰符
- 类或结构可以实现多个接口。类可以继承基类,并实现一个和多个接口
接口的使用
接口与抽象类
接口与抽象类非常相似,它定义了一些未实现的属性和方法。所有继承它的类都继承这些成员,在这个角度上,可以把接口理解为一个类的模板。接口最终的目的是起到统一的作用
- 两者都包含可以由子类继承的抽象成员
- 两者都不直接实例化
接口与抽象类区别
- 抽象类除拥有抽象成员之外,还可以拥有非抽象成员;而接口所有的成员都是抽象的
- 抽象成员默认是私有的,而接口的成员默认是公有的。
- 接口中不能含有构造函数、析构函数、静态成员和常量
- C#只支持单继承,即子类只能继承一个父类,而一个子类却能够实现多个接口
泛型
我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int数据,另一个是处string数据,或者其他自定义的数据类型,但我们没有办法,只能分别写多个方法处理每个数据类型,因为方法的参数类型不同
你可能会想到用object,来解决这个问题。但是,缺陷的:
1.会出现装箱、折箱操作,这将在托管堆上分配和回收大量的变量,若数据量大,则性能损失非常严重。
2.在处理引用类型时,虽然没有装箱和折箱操作,但将用到数据类型的强制转换操作,增加处理器的负担。
介绍泛型
C#中的泛型能够将类型作为参数来传递,即在创建类型时用一个特定的符号如“T”来作为一个占位符,代替实际的类型,等待在实例化时用一个实际的类型来代替。
public class Test<T>
{
public void Swap(T a,T b)
{
}
}
泛型的优点
- 使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。
- 降低了强制转换或装箱操作的成本或风险
- 可以对泛型类进行约束以访问特定数据类型的方法。
泛型的限制
void MyFunc<T>(T x, T y)
{
x = x + y;//报错!泛型的变量不能使用运算符’+’
}
泛型成员因类型不确定,可能是类、结构体、字符、枚举……
所以不能使用算术运算符、比较运算符等进行运算!
注意,可以使用赋值运算符
泛型类型参数
类型参数
在泛型类型或方法定义中,类型参数是客户端在实例化泛型类型的变量时指定的特定类型的占位符
不可以像这样使用,因为它实际上并不是一个类型,而更像是一个类型的蓝图。
注意
- 类型参数并不是只有一个,可以有多个
- 类型参数可以是编译器识别的任何类型。
- 类型参数的名字不能随便起,不能重名
类型参数的约束
在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。 如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。 这些限制称为约束。 约束是使用 where 上下文关键字指定的。
泛型类和泛型方法
泛型类
泛型类最常用于集合。 像从集合中添加和移除项这样的操作,大体上相同.
创建泛型类的过程为:从一个现有的具体类开始,逐一将每个类型更改为类型参数,直至达到通用化和可用性的最佳平衡。
泛型方法
创建泛型方法的过程和泛型类相似。泛型方法是使用类型参数声明的方法,如图: