泛型方法
现在有这样一个需求,定义一个方法,要求传入什么数据就返回什么数据。我们可以这样写:
String getData(String value){
return value;
}
复制
上例中是传入一个字符串,然后返回该字符串。那么当我要是传入一个int类型的数据的时候呢?此时我们可以定义多个方法,如下:
String getData(String value){
return value;
}
int getData1(int value){
return value;
}
List getData2(List value){
return value;
}
复制
也就是说,我们想要传入什么类型的 数据,就调用对应的方法。但是这样的话,代码就冗余了。其实,我们完全可以不指定传入参数的类型以及返回的类型,如下:
getData(value){
return value;
}
复制
这样的话,我们就可以传入任意类型的数据了,传入什么类型的数据,返回的就是该类型的该数据。但是这样做还是有一个弊端的,就是不能做类型检查了。也就是说,我们不能够限制传入数据的类型了。那么在这种情况下,就引出我们今天的主角——泛型了。
下面是我将方法定义成一个泛型方法:
T getData<T>(T value){
return value;
}
复制
T表示一个泛型,也就是任意类型。我们不一定非得使用T来表示泛型,可以使用任意的字母来代替,不过一般是使用T来代表泛型。
然后我们可以像普通方法一样来使用它:
print(getData(123));
复制
如果我们想让该方法有类型校验的话,可以这样写:

我们看到,<String>表示传入的数据类型必须是String,上例中我传入了int类型的123,所以程序就报错了。
通过上面的分析,我们可知,泛型方法能解决两个问题:
1,代码复用,避免代码冗余;
2,对不确定的数据类型进行类型校验。
泛型类
实际上,List就是一个泛型类,我们可以给List指定元素的类型。
比如下面这段代码:
main(){
List mylist = new List();
mylist.add('123Str');
mylist.add(123);
print(mylist);
}
复制
我给mylist添加了两个元素,一个元素是String类型,一个是int类型。但是一般而言,List中的元素类型要保持一致,此时就要通过泛型来实现。如下:
List mylist = new List<String>();
复制
此时再给mylist增加元素,元素类型就只能是String,如果是其他类型就会报错。
那么泛型类如果定义呢?接下来给大家演示一下。
首先新建一个普通的类:
class PrintClass{
List dataList = new List();
addObject(value){
this.dataList.add(value);
}
printInfo(){
for (var item in this.dataList) {
print(item);
}
}
}
复制
使用如下:
main(){
var printObject = new PrintClass();
printObject.addObject(1);
printObject.addObject('2str');
printObject.printInfo();
}
复制
此时,如果我想限制PrintClass类的addObject方法传入数据的类型,那么就将该类创建成一个泛型类:
class PrintClass<T>{
List dataList = new List<T>();
addObject(T value){
this.dataList.add(value);
}
printInfo(){
for (var item in this.dataList) {
print(item);
}
}
}
复制
使用如下:
该例中,第二行代码被挡住了,如下:
var printObject = new PrintClass<String>();
复制
这时,给addObject方法传的参数就限制为String类型,如果传了其他类型的参数,那么就会在运行的时候报错。
泛型接口
前文我们提到,在Dart中,一般通过抽象类来定义接口。
所以泛型接口的定义完全可以参考泛型类的定义。
再次总结一下,泛型不但可以解决代码重用的问题,还可以对不确定类型进行类型校验。