文章目录

  • 一、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 泛型 ( 泛型类 | 泛型方法 | 特定类型约束的泛型 )相关推荐

  1. 鸟欲高飞先振翅,人求上进先读书 [泛型 泛型类 泛型方法 泛型接口 泛型通配符详解]

    文章目录 5. 泛型 5.1 泛型概述[理解] 5.2 为什么会引入泛型? 5.3 泛型的好处 5.4 泛型的定义格式 5.5 泛型类[应用] 5.6 泛型方法 5.7 泛型接口[应用] 5.8类型通 ...

  2. java 泛型 泛型类(Generic Classes)类型形参(Type Parameters)

    类(class)的类型形参的作用范围是整个class,除了静态(static)成员和静态初始化模块. class Test <T> { //类型形参的写法static {Test<T ...

  3. C#读取数据库返回泛型集合 把DataSet类型转换为ListT泛型集合

    /// <summary>/// 获取UserInfo泛型集合/// </summary>/// <param name="connStr">数 ...

  4. Java:高级之泛型概念引入,泛型可以设置多个类型参数,泛型继承和泛型接口实现,限制泛型可用类型,泛型通配的方式,泛型方法,泛型方法限制泛型可用类型

    目录页         泛型简介         泛型类         限制泛型可用类型         类型通配声明         泛型方法 问题引入 如果我们需要产生多个对象,每个对象的逻辑完 ...

  5. C#中的泛型 / 泛型类 / 数组、ArrayList和List三者的区别

    C#中数组.ArrayList和List三者的区别 在C#中数组,ArrayList,List都能够存储一组对象,那么这三者到底有什么样的区别呢. 数组 数组在C#中最早出现的.在内存中是连续存储的, ...

  6. Java获取泛型类的实际类型的实例

    文章目录 泛型速解 强类型 共用性 继承泛型父类获取具体类型的实例 泛型速解 泛型是类型的参数. 强类型 在JDK中,最常见的的用法就是容器类的元素类型的指定.以List为例,通过List<元素 ...

  7. 什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的

    1. 泛型的定义和意义 1.1 什么叫泛型? 泛型,顾名思义就是广泛的类型,专业术语为"参数化类型":当我们创建对象时没指定类型,任何引用类型都可以使用,兼容多种数据类型.如果是基 ...

  8. 第五节:泛型(泛型类、接口、方法、委托、泛型约束、泛型缓存、逆变和协变)

    一. 泛型诞生的背景 在介绍背景之前,先来看一个案例,要求:分别输出实体model1.model2.model3的id和name值,这三个实体有相同的属性名字id和name. 1 public cla ...

  9. 【Java 泛型】泛型简介 ( 泛型类 | 泛型方法 | 静态方法的泛型 | 泛型类与泛型方法完整示例 )

    文章目录 一.泛型简介 二.泛型类 三.泛型方法 四.静态方法的泛型 五.泛型类与泛型方法完整示例 一.泛型简介 泛型 可以 简单理解为 参数化类型 , 主要作用在 类 , 方法 , 接口 上 ; j ...

最新文章

  1. NIO详解(三):IO多路复用模型之select、poll、epoll
  2. Ehcache学习笔记(一)基础入门
  3. jigsaw kaggle_使用Project Jigsaw的JDK 9 Early Access上的Eclipse IDE
  4. 最短寻道时间算法c语言,如果北京到上海有千亿条路,寻找最短路径用C语言编程用枚举法没效率,应该用什么算法才能高效解决它?...
  5. xbox360无线手柄接收器驱动_创新设计的多模手柄,北通宙斯T6精英机械游戏手柄体验点评...
  6. js对象写入键值对_41 利用字面量创建对象
  7. easyui的datagrid的editor为combobox,根据每个row的属性的不同,如何动态的设置每个row的combobox的url...
  8. 安全测试之sql注入
  9. 【云服务器】阿里云服务器+宝塔Linux零成本搭建全网音乐搜索引擎网站(在线音乐播放器),可在线播放可下载可分享它不香么?
  10. python 频谱图_SciPy spectrogram:计算频谱图
  11. linux嵌入式工控机编程,Linux嵌入式工控机的特点
  12. 一大堆模块的结晶……
  13. 4 变量、作用域与内存
  14. 【Bug】steam双方都是国区 礼物无法入库问题
  15. 老师上课也能涨粉?胖超说艺考坐拥千万粉丝靠什么?
  16. 一刀工具箱 - 网站权重查询工具
  17. 360极速浏览器国际版?
  18. 多通道主控的多CE NAND Flash 动态块模型
  19. ADSL宽带使用中的各种技术故障问题
  20. php 木马 加密,PHP后门木马详解

热门文章

  1. 十五分钟上手SoFlu全自动软件工程平台
  2. 我花了10天学习全自动软件开发,结果居然.....
  3. 不会数据分析?无从下手?一文帮你打开数据分析思路
  4. CSS--弹性布局(Flex-Layout)
  5. 办公软件 Word2010 所有操作界面
  6. html页面推送功能的实现,想实现Web页面内容自动更新?你需要了解WEB实时推送技术!...
  7. Python - 入门
  8. 笔记:Oracle报错:ORA-22858 invalid alteration of datatype
  9. 关于thinkpad t400 安装Ubuntu 12.04 后的几个问题
  10. HTML5七夕情人节表白网页制作【情人节满屏爱心HTML5特效】HTML+CSS+JavaScript html生日快乐祝福网页制作