【Flutter】Dart 泛型 ( 泛型类 | 泛型方法 | 特定类型约束的泛型 )
一、Dart 泛型类与泛型方法
泛型作用 : 为 类 , 接口 , 方法 提供复用性 , 支持类型不确定的数据类型 ;
泛型类 : 提高代码复用程度 ;
泛型方法 : 参数或返回值有泛型类型约束 , 参数或返回值类型必须符合对应的泛型类型 , 泛型使用时会进行类型检查约束 , 如果设置错误的类型 , 编译时报错 ;
泛型类示例 :
/// 泛型作用 : 为 类 , 接口 , 方法 提供复用性 , 支持类型不确定的数据类型
///
/// 泛型类 : 提高代码复用程度
/// 该类是一个缓存类 , 缓存的数据类型是 T 泛型 , 该类型可以是任意类型
class Cache<T>{
/// 缓存数据存储到该 Map 集合中
Map<String, Object> _map = Map();
/// 设置泛型缓存数据 , 该方法是泛型方法
/// 此处将 T 类型的数据存放到 map 集合中
void setCacheItem(String key, T value){
_map[key] = value;
}
/// 取出泛型缓存数据 , 该方法是泛型方法
T getCachedItem(String key){
return _map[key];
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
测试上述泛型类 :
/// 泛型测试类
class Generic{
/// 该方法测试泛型类及泛型方法
void test(){
// 创建泛型类对象 , 泛型类型设置为 String 类型
Cache<String> cache = Cache();
// 调用泛型方法时 , 传入的参数必须符合对应的泛型类型
// 泛型约束 : 泛型使用时会进行类型检查约束 , 如果设置错误的类型 , 编译时报错
cache.setCacheItem("name", "Tom");
// 获取缓存内容
String value = cache.getCachedItem("name");
print("泛型测试, 类型字符串, 获取的缓存内容为 ${value}");
// 创建泛型类对象 , 泛型类型设置为 int 类型
Cache<int> cache2 = Cache();
// 调用泛型方法时 , 传入的参数必须符合对应的泛型类型
// 泛型约束 : 泛型使用时会进行类型检查约束 , 如果设置错误的类型 , 编译时报错
cache2.setCacheItem("age", 18);
// 获取缓存内容
int value2 = cache2.getCachedItem("age");
print("泛型测试, 类型整型, 获取的缓存内容为 ${value2}");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
打印结果 :
I/flutter (24673): 泛型测试, 类型字符串, 获取的缓存内容为 Tom
I/flutter (24673): 泛型测试, 类型整型, 获取的缓存内容为 18
- 1
- 2
二、Dart 泛型中的特定类型约束
泛型还可以进行特定类型约束 , 如指定该泛型类型必须是某个类的子类 , 使用 <T extends Person> 约束该泛型必须是某个类的子类 ;
泛型类示例代码 :
/// 泛型中的特定类型约束
/// 将泛型约束为某个类型的子类
class Member<T extends Person>{
T _person;
/// 构造函数中设置 T _person 成员的值
Member(this._person);
/// 获取 _person 的名字
String getName(){
return _person.name;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
上述涉及到的两个类在 【Flutter】Dart 面向对象 ( 命名构造方法 | 工厂构造方法 | 命名工厂构造方法 ) 中定义 ;
测试上述泛型类 :
/// 泛型类测试
/// 类泛型要求是 T extends Person , 泛型类型必须是 Person 的子类
/// Student 是 Person 的子类
Member<Student> member = Member(Student(6, "Tom", 18));
String name = member.getName();
print("泛型类测试, 获取的 T extends Person 泛型的 name 字段为 ${name}");
- 1
- 2
- 3
- 4
- 5
- 6
测试打印结果 :
I/flutter (24673): 泛型类测试, 获取的 T extends Person 泛型的 name 字段为 Tom
- 1
三、Dart 自带泛型
在 Flutter 的 main.dart 中的 State 就是泛型类 ;
class _MyHomePageState extends State<MyHomePage> {
}
- 1
- 2
State 类中要求一个泛型 T , 该泛型类型必须继承 StatefulWidget 类 ;
abstract class State<T extends StatefulWidget> extends Diagnosticable {
}
- 1
- 2
此处的 MyHomePage 就是 泛型类型 , 是 StatefulWidget 类的子类 , 符合 泛型要求 ;
四、完整代码示例
泛型类 , 泛型方法 , 泛型测试相关代码 :
import 'package:flutterapphello/Dart_OOP.dart';
/// 泛型测试类
class Generic{
/// 该方法测试泛型类及泛型方法
void test(){
// 创建泛型类对象 , 泛型类型设置为 String 类型
Cache<String> cache = Cache();
// 调用泛型方法时 , 传入的参数必须符合对应的泛型类型
// 泛型约束 : 泛型使用时会进行类型检查约束 , 如果设置错误的类型 , 编译时报错
cache.setCacheItem("name", "Tom");
// 获取缓存内容
String value = cache.getCachedItem("name");
print("泛型测试, 类型字符串, 获取的缓存内容为 ${value}");
// 创建泛型类对象 , 泛型类型设置为 int 类型
Cache<int> cache2 = Cache();
// 调用泛型方法时 , 传入的参数必须符合对应的泛型类型
// 泛型约束 : 泛型使用时会进行类型检查约束 , 如果设置错误的类型 , 编译时报错
cache2.setCacheItem("age", 18);
// 获取缓存内容
int value2 = cache2.getCachedItem("age");
print("泛型测试, 类型整型, 获取的缓存内容为 ${value2}");
/// 泛型类测试
/// 类泛型要求是 T extends Person , 泛型类型必须是 Person 的子类
/// Student 是 Person 的子类
Member<Student> member = Member(Student(6, "Tom", 18));
String name = member.getName();
print("泛型类测试, 获取的 T extends Person 泛型的 name 字段为 ${name}");
}
}
/// 泛型作用 : 为 类 , 接口 , 方法 提供复用性 , 支持类型不确定的数据类型
///
/// 泛型类 : 提高代码复用程度
/// 该类是一个缓存类 , 缓存的数据类型是 T 泛型 , 该类型可以是任意类型
class Cache<T>{
/// 缓存数据存储到该 Map 集合中
Map<String, Object> _map = Map();
/// 设置泛型缓存数据 , 该方法是泛型方法
/// 此处将 T 类型的数据存放到 map 集合中
void setCacheItem(String key, T value){
_map[key] = value;
}
/// 取出泛型缓存数据 , 该方法是泛型方法
T getCachedItem(String key){
return _map[key];
}
}
/// 泛型中的特定类型约束
/// 将泛型约束为某个类型的子类
class Member<T extends Person>{
T _person;
/// 构造函数中设置 T _person 成员的值
Member(this._person);
/// 获取 _person 的名字
String getName(){
return _person.name;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
涉及到的 Person 和 Student 类 :
/// 定义 Dart 类
/// 与 Java 语言类似, 所有的类默认继承 Object 类
class Person{
/// 定义变量
String name;
int age;
/// 私有字段
int _achievement;
/// 标准构造方法, 下面的方法是常用的构造方法写法
Person(this.name, this.age);
/// get 方法 : 设置私有字段 achievement 的 get 方法,
/// 让外界可以访问 Person 对象的 _achievement 私有成员
int get achievement => _achievement;
/// set 方法 : 设置私有字段 achievement 的 set 方法,
/// 让外界可以设置 Person 对象的 _achievement 私有成员值
set achievement(int achievement){
_achievement = achievement;
}
/// 静态方法 , 通过类名调用
static log(){
print("log");
}
/// 重写父类的方法
@override
String toString() {
return "$name : $age";
}
}
/// 继承
class Student extends Person{
/// 私有变量, 以下划线开始的变量是私有变量
int _grade;
String school;
String city;
String address;
/// 父类构造函数调用 : 如果父类有非空参数的构造函数, 子类必须实现相同参数的构造函数
/// 如果该类有父类 , 那么先调用父类的构造方法 , 完成父类的初始化
/// 然后才能完成自己的初始化
///
/// this.school 指定自有参数
/// {this.school} 是可选参数, 可选参数必须在构造函数参数列表中最后一个
///
/// 默认参数 : 可选参数中如果用户不初始化该可选参数 , 那么为其指定一个默认值
/// {this.city = "北京"} 指定了如果用户不初始化 city 变量, 那么为其初始化 "北京" 字符串值
///
/// 初始化列表 : 冒号后面的内容就是初始化列表
/// 父类构造器也是初始化列表
/// 除了父类构造方法之外 , 还可以在子类构造方法体之前初始化示例变量
/// 不同的初始化实例变量之间使用逗号隔开
///
/// 父类构造方法 : 如果父类没有默认构造方法 (无参构造方法) ,
/// 必须在初始化列表中调用父类构造函数 , super(name, age) ;
///
/// 构造方法方法体 : 可以省略 ;
Student(this._grade, String name, int age,
{this.school, this.city = "北京"})
: address = "北京市海淀区" ,
super(name, age);
// 命名构造方法
// 定义格式 : 类名.方法名()
// 父类构造函数 : 如果父类没有默认构造函数, 子类必须调用父类的构造函数
Student.cover(Student student):super(student.name, student.age);
// 命名构造方法也可以有方法体
Student.init(Student student):super(student.name, student.age){
print("命名构造方法 : name : ${student.name}, age : ${student.age}");
}
// 命名工厂构造方法 : factory 类名.方法名
// 命名工厂构造方法可以有返回值
// 如果类中有 final 修饰的成员 , 在命名构造方法中必须对其进行初始化
// 但是在命名工厂构造方法中 , 可以不初始化 final 类型成员
// 命名工厂构造方法可以有返回值
factory Student.init2(){
return Student(1, "Tom", 18);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
测试代码入口 : 在 main.dart 中的 _MyHomePageState 类中的 build 方法中 ;
/// 省略其它源码
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
// 测试泛型
Generic generic = Generic();
generic.test();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
打印结果 :
I/flutter (24673): 泛型测试, 类型字符串, 获取的缓存内容为 Tom
I/flutter (24673): 泛型测试, 类型整型, 获取的缓存内容为 18
I/flutter (24673): 泛型类测试, 获取的 T extends Person 泛型的 name 字段为 Tom
- 1
- 2
- 3
五、 相关资源
参考资料 :
- Flutter 官网 : https://flutter.dev/
- Flutter 开发文档 : https://flutter.cn/docs ( 强烈推荐 )
- 官方 GitHub 地址 : https://github.com/flutter
- Flutter 中文社区 : https://flutter.cn/
- Flutter 实用教程 : https://flutter.cn/docs/cookbook
- Flutter CodeLab : https://codelabs.flutter-io.cn/
- Dart 中文文档 : https://dart.cn/
- Dart 开发者官网 : https://api.dart.dev/
- Flutter 中文网 ( 非官方 , 翻译的很好 ) : https://flutterchina.club/ , http://flutter.axuer.com/docs/
- Flutter 相关问题 : https://flutterchina.club/faq/ ( 入门阶段推荐看一遍 )
博客源码下载 :
-
GitHub 地址 : https://github.com/han1202012/flutter_app_hello ( 随博客进度一直更新 , 有可能没有本博客的源码 )
-
博客源码快照 : https://download.csdn.net/download/han1202012/15463304( 本篇博客的源码快照 , 可以找到本博客的源码 )
文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。
原文链接:hanshuliang.blog.csdn.net/article/details/114059611
- 点赞
- 收藏
- 关注作者
评论(0)