【Flutter】Dart 泛型 ( 泛型类 | 泛型方法 | 特定类型约束的泛型 )
文章目录
- 一、Dart 泛型类与泛型方法
- 二、Dart 泛型中的特定类型约束
- 三、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];}
}
测试上述泛型类 :
/// 泛型测试类
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}");}}
打印结果 :
I/flutter (24673): 泛型测试, 类型字符串, 获取的缓存内容为 Tom
I/flutter (24673): 泛型测试, 类型整型, 获取的缓存内容为 18
二、Dart 泛型中的特定类型约束
泛型还可以进行特定类型约束 , 如指定该泛型类型必须是某个类的子类 , 使用 <T extends Person> 约束该泛型必须是某个类的子类 ;
泛型类示例代码 :
/// 泛型中的特定类型约束
/// 将泛型约束为某个类型的子类
class Member<T extends Person>{T _person;/// 构造函数中设置 T _person 成员的值Member(this._person);/// 获取 _person 的名字String getName(){return _person.name;}
}
上述涉及到的两个类在 【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}");
测试打印结果 :
I/flutter (24673): 泛型类测试, 获取的 T extends Person 泛型的 name 字段为 Tom
三、Dart 自带泛型
在 Flutter 的 main.dart 中的 State 就是泛型类 ;
class _MyHomePageState extends State<MyHomePage> {}
State 类中要求一个泛型 T , 该泛型类型必须继承 StatefulWidget 类 ;
abstract class State<T extends StatefulWidget> extends Diagnosticable {}
此处的 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;}
}
涉及到的 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");}/// 重写父类的方法@overrideString 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);}}
测试代码入口 : 在 main.dart 中的 _MyHomePageState 类中的 build 方法中 ;
/// 省略其它源码
class _MyHomePageState extends State<MyHomePage> {@overrideWidget build(BuildContext context) {// 测试泛型Generic generic = Generic();generic.test();}
}
打印结果 :
I/flutter (24673): 泛型测试, 类型字符串, 获取的缓存内容为 Tom
I/flutter (24673): 泛型测试, 类型整型, 获取的缓存内容为 18
I/flutter (24673): 泛型类测试, 获取的 T extends Person 泛型的 name 字段为 Tom
五、 相关资源
参考资料 :
- 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( 本篇博客的源码快照 , 可以找到本博客的源码 )
【Flutter】Dart 泛型 ( 泛型类 | 泛型方法 | 特定类型约束的泛型 )相关推荐
- 鸟欲高飞先振翅,人求上进先读书 [泛型 泛型类 泛型方法 泛型接口 泛型通配符详解]
文章目录 5. 泛型 5.1 泛型概述[理解] 5.2 为什么会引入泛型? 5.3 泛型的好处 5.4 泛型的定义格式 5.5 泛型类[应用] 5.6 泛型方法 5.7 泛型接口[应用] 5.8类型通 ...
- java 泛型 泛型类(Generic Classes)类型形参(Type Parameters)
类(class)的类型形参的作用范围是整个class,除了静态(static)成员和静态初始化模块. class Test <T> { //类型形参的写法static {Test<T ...
- C#读取数据库返回泛型集合 把DataSet类型转换为ListT泛型集合
/// <summary>/// 获取UserInfo泛型集合/// </summary>/// <param name="connStr">数 ...
- Java:高级之泛型概念引入,泛型可以设置多个类型参数,泛型继承和泛型接口实现,限制泛型可用类型,泛型通配的方式,泛型方法,泛型方法限制泛型可用类型
目录页 泛型简介 泛型类 限制泛型可用类型 类型通配声明 泛型方法 问题引入 如果我们需要产生多个对象,每个对象的逻辑完 ...
- C#中的泛型 / 泛型类 / 数组、ArrayList和List三者的区别
C#中数组.ArrayList和List三者的区别 在C#中数组,ArrayList,List都能够存储一组对象,那么这三者到底有什么样的区别呢. 数组 数组在C#中最早出现的.在内存中是连续存储的, ...
- Java获取泛型类的实际类型的实例
文章目录 泛型速解 强类型 共用性 继承泛型父类获取具体类型的实例 泛型速解 泛型是类型的参数. 强类型 在JDK中,最常见的的用法就是容器类的元素类型的指定.以List为例,通过List<元素 ...
- 什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的
1. 泛型的定义和意义 1.1 什么叫泛型? 泛型,顾名思义就是广泛的类型,专业术语为"参数化类型":当我们创建对象时没指定类型,任何引用类型都可以使用,兼容多种数据类型.如果是基 ...
- 第五节:泛型(泛型类、接口、方法、委托、泛型约束、泛型缓存、逆变和协变)
一. 泛型诞生的背景 在介绍背景之前,先来看一个案例,要求:分别输出实体model1.model2.model3的id和name值,这三个实体有相同的属性名字id和name. 1 public cla ...
- 【Java 泛型】泛型简介 ( 泛型类 | 泛型方法 | 静态方法的泛型 | 泛型类与泛型方法完整示例 )
文章目录 一.泛型简介 二.泛型类 三.泛型方法 四.静态方法的泛型 五.泛型类与泛型方法完整示例 一.泛型简介 泛型 可以 简单理解为 参数化类型 , 主要作用在 类 , 方法 , 接口 上 ; j ...
最新文章
- NIO详解(三):IO多路复用模型之select、poll、epoll
- Ehcache学习笔记(一)基础入门
- jigsaw kaggle_使用Project Jigsaw的JDK 9 Early Access上的Eclipse IDE
- 最短寻道时间算法c语言,如果北京到上海有千亿条路,寻找最短路径用C语言编程用枚举法没效率,应该用什么算法才能高效解决它?...
- xbox360无线手柄接收器驱动_创新设计的多模手柄,北通宙斯T6精英机械游戏手柄体验点评...
- js对象写入键值对_41 利用字面量创建对象
- easyui的datagrid的editor为combobox,根据每个row的属性的不同,如何动态的设置每个row的combobox的url...
- 安全测试之sql注入
- 【云服务器】阿里云服务器+宝塔Linux零成本搭建全网音乐搜索引擎网站(在线音乐播放器),可在线播放可下载可分享它不香么?
- python 频谱图_SciPy spectrogram:计算频谱图
- linux嵌入式工控机编程,Linux嵌入式工控机的特点
- 一大堆模块的结晶……
- 4 变量、作用域与内存
- 【Bug】steam双方都是国区 礼物无法入库问题
- 老师上课也能涨粉?胖超说艺考坐拥千万粉丝靠什么?
- 一刀工具箱 - 网站权重查询工具
- 360极速浏览器国际版?
- 多通道主控的多CE NAND Flash 动态块模型
- ADSL宽带使用中的各种技术故障问题
- php 木马 加密,PHP后门木马详解
热门文章
- 十五分钟上手SoFlu全自动软件工程平台
- 我花了10天学习全自动软件开发,结果居然.....
- 不会数据分析?无从下手?一文帮你打开数据分析思路
- CSS--弹性布局(Flex-Layout)
- 办公软件 Word2010 所有操作界面
- html页面推送功能的实现,想实现Web页面内容自动更新?你需要了解WEB实时推送技术!...
- Python - 入门
- 笔记:Oracle报错:ORA-22858 invalid alteration of datatype
- 关于thinkpad t400 安装Ubuntu 12.04 后的几个问题
- HTML5七夕情人节表白网页制作【情人节满屏爱心HTML5特效】HTML+CSS+JavaScript html生日快乐祝福网页制作