前言

​ 在学习Flutter源码的时候,看到各种复杂的mixin和on,为了便于后续Flutter的学习,这里有必要一起来份详细Dart 的 Mixin机制。

什么是mixins

首先看看官方文档的定义:

Mixins are a way of reusing a class’s code in multiple class hierarchies.

即:Mixins是用来复用多个类之间的代码,减少耦合。

再来看看维基百科对它的定义:

mixin是面向对象程序设计语言中的类,提供了方法的实现。其他类可以访问mixin类的方法、变量而不必成为其子类。

这两种解释我任务维基百科描述的更通俗一点,下面我们来详细解释:

讲解

假如我们有两个类A,B,现在需要使用mixins定义类T

class T = A with B;
//或
class T extends A with B {}

那么我们得到结果class T是什么样的? 假设我们A类中的所有方法为AM,B类中所有的方法集合叫BM,那么T中的方法集合就为:

BM U (AM-BM)

即:T中的方法为A 和 B类中方法的集合,如果有重复方法,取B中的方法(with 最右侧的方法)

上面伪代码就是最直接简单的方式,相信大家应该都能看懂。下面我们来举个例子详细介绍一下

我们来举几个例子

1. A with B

//A
class A {a() {print('A.a()');}b() {print('A.b()');}
}
//B
class B {a() {print('B.a()');}
}
//Z
class Z extends A with B {}void main() {Z z = Z();z.a();
}

根据上面伪代码AM U (AM-BM)讲解(Z的方法为A,B方法集合,有重复方法取with最右边类的方法),得出Z类中最终包含的方法应该是:B.a(),A.b()

代码输出结果是:

B.a()

2. A with B,C

A with B, C可以理解为:(A with B) with C

//A
class A {a() {print('A.a()');}b() {print('A.b()');}
}//B
class B {a() {print('B.a()');}b() {print('B.b()');}c() {print('B.c()');}
}//C
class C {a() {print('C.a()');}
}//Z
class Z extends A with B, C {}void main() {Z z = new Z();z.a();z.b();z.c();
}

根据上面的逻辑整理最终方法集合公式为CM U (BM - CM) U (AM - BM - CM),最终Z包含的方法应该是:C.a(), B.b(), B.c()

代码输出结果是:

C.a()
B.b()
B.c()

下面是重点关注容易被忽略的关于mixin机制里面super的注意事项

abstract class BaseA {BaseA() {initInstances();}initInstances() {//do nothing}
}mixin B on BaseA {@overrideinitInstances() {super.initInstances();print('B');}
}mixin C on BaseA {@overrideinitInstances() {super.initInstances();print('C');}
}mixin D on BaseA {@overrideinitInstances() {super.initInstances();print('D');}
}class T extends BaseA with B, C, D {static void init() {T();}
}void main() {T.init();
}

相信上面的代码如果删除B,C,D各个类里面的super.initInstances()方法调用就很容易得出结论知道输出结果是:D。

但是这里加上super.initInstances()调用结果却截然不同,我们只需要理解在mixin机制中,每调用一个方法都会类似从最右边开始查找需要调用的方法,一直查找到最左边的基类,一旦找到就停止查找然后调用到该方法。super也是类似,通过super.method调用的方法,会从当前类往左去查找metod方法;所以上面代码的输出结果就是:B,C,D

思考:上面如果我们将B,C,D类中的super.initInstances()和print(’*’)顺序颠倒过来会输出什么

总结

​ 关于Mixins还有很多需要注意的细节,这里我们需要通过demo多多练习,有时候通过Mixin机制我们可以跨越多个类的层次实现代码的重用,特别是Mixins机制中super的使用,在Flutter源码中也经常使用,需要多多练习才能理解透彻。

​ 本文主要是自己通过Demo的 一些理解,如果有不同的见解,欢迎评论交流。

思考

下面模拟Flutter runApp中WidgetsFlutterBinding初始化的方式,思考下输出的是什么:

abstract class BindingBase {BindingBase() {print('constructor A');initInstances();}initInstances() {//do nothing}
}mixin ABinding on BindingBase {@overrideinitInstances() {super.initInstances();print('ABinding.initInstances()');}
}mixin BBinding on BindingBase {@overrideinitInstances() {super.initInstances();print('BBinding.initInstances()');}
}mixin CBinding on BindingBase {@overrideinitInstances() {super.initInstances();print('CBinding.initInstances()');}
}class WidgetsFlutterBinding extends BindingBasewith ABinding, BBinding, CBinding {static void ensureInitialized() {WidgetsFlutterBinding();}
}void main() {WidgetsFlutterBinding.ensureInitialized();
}

欢迎评论区给出答案讨论

小白都能看懂的关于Mixins机制的理解相关推荐

  1. 随机森林的特征 是放回抽样么_机器学习超详细实践攻略(10):随机森林算法详解及小白都能看懂的调参指南...

    一.什么是随机森林 前面我们已经介绍了决策树的基本原理和使用.但是决策树有一个很大的缺陷:因为决策树会非常细致地划分样本,如果决策树分得太多细致,会导致其在训练集上出现过拟合,而如果决策树粗略地划分样 ...

  2. 小白都能看懂的实战教程 手把手教你Python Web全栈开发(DAY 3)

    小白都能看懂的实战教程 手把手教你Python Web全栈开发 Flask(Python Web)实战系列之在线论坛系统 第三讲 这是小白都能看懂的实战教程 手把手教你Python Web全栈开发 的 ...

  3. c语言程序和plc程序的区别,一文告诉你PLC与计算机的本质区别在哪里!小白都能看懂!...

    原标题:一文告诉你PLC与计算机的本质区别在哪里!小白都能看懂! 你真的了解PLC吗?你知道PLC与计算机的本质区别吗?我来简单解释一下吧. 1.PLC可以工作在极其恶劣的电磁环境中 如果我们把计算机 ...

  4. 小白都能看懂的实战教程 手把手教你Python Web全栈开发(DAY 1)

    小白都能看懂的实战教程 手把手教你Python Web全栈开发 Flask(Python Web)实战系列之在线论坛系统 第一讲 博主博客文章内容导航(实时更新) 更多优质文章推荐: 收藏!最详细的P ...

  5. 红色买绿色出 简单易操作的买卖点公式 散户小白都能看懂

    好久没来csdn了,在最初,CSDN是用来记录我做前端写的笔记,后面在工作期间,接触了产品,就转岗了,慢慢的,csdn就很少写了,但是我觉得这里可以作为我记录心得的一个地方,还是挺好的. 因为产品规划 ...

  6. 兄弟,用大白话告诉你小白都能看懂的Hadoop架构原理

    本文来自:石杉的架构笔记 目录 一.前奏 二.HDFS的NameNode架构原理 一.前奏 Hadoop是目前大数据领域最主流的一套技术体系,包含了多种技术. 包括HDFS(分布式文件系统),YARN ...

  7. 兄弟,用大白话给你讲小白都能看懂的分布式系统容错架构

    点击上方"蓝字", 右上角选择"设为星标" 周一至周五早11点半!精品文章准时送上! 本文来自石杉的架构笔记 目录 (1)TB级数据放在一台机器上:难啊! (2 ...

  8. 黑苹果电池电量补丁_小白都能看懂的DSDT电量显示补丁教程

    [TOC] 简介 知识储备DSDT 正则匹配(不懂就依葫芦画瓢) 背景 由于普通PC的电池设备并不兼容与苹果的SMbus设备,所以,对于黑苹果,只能够通过ACPI来获取电池状态.为了解决电量显示我可是 ...

  9. BUI框架中 使用Jpush极光推送,单推跟群推,尽量让小白都能看懂

    1.先贴一下自己使用的Cordvoa版本 2.再贴一下自己使用的极光推送版本 3.极光推送GitHub地址:点击打开 4.小白常见问题 Crodova打包,编译出错. Crodova打包后,提示JPu ...

最新文章

  1. dqn在训练过程中loss越来越大_DQN算法实现注意事项及排错方法
  2. 2059 - authentication plugin 'caching_sha2_password' -navicat连接异常问题解决
  3. C#里枚举类型以及值引用和地址引用差别演示代码
  4. 解决python中 .to_csv() 的乱码问题
  5. matlab 样本均值,Matlab | Matlab从入门到放弃(4)——样本均值
  6. sublime 常用快捷键
  7. Android性能全面分析与优化方案研究—几乎是史上最全最实用的
  8. 右键菜单 GenericMenu
  9. Spring异步切面源码解析
  10. [已解决]360极速浏览器.为什么后台一直占用20%的cpu?
  11. “青山依旧在,几度夕阳红” 2021.12.7日晚
  12. GitHub压缩包下载URL
  13. Codeforces Round #548 (Div. 2) C. Edgy Trees(dfs || 并查集)
  14. Android Studio连接mysql8.0.25经验贴(三天血与泪的教训)
  15. 前端开发中环境变量配置
  16. Brendan Collins:物联网如何改变了你对存储的看法
  17. 【数据库02】==== 表的增删改查(基础)
  18. 科学计量学类毕业论文文献有哪些?
  19. sharepoint 2010 社区中心系统-在线问答-扩展讨论板Dicussion答复功能
  20. python中options是什么意思_在OPTIONS方法中显示棉花糖模式的描述

热门文章

  1. 建设“智慧城市”、“智慧社区”远程控制开关智能微型断路器哪家好?——安科瑞 严新亚
  2. VUI-百度语音之Rest接口python学习笔记0
  3. 有苦有乐的算法 --- 使用队列结构实现栈结构
  4. 中国石油大学《计算机文化基础》在线考试题
  5. 大学计算机未来五年规划,大学生活评价与未来五年计划(8页)-原创力文档
  6. 临界区例子及相关函数翻译
  7. 记今年阿里巴巴招聘的几个失误
  8. 爬取携程和蚂蜂窝的景点评论数据\携程评论数据爬取\旅游网站数据爬取
  9. 搜索 SAP成都研究院廖婧:SAP C4C社交媒体集成概述
  10. Root Moto X Style XT1570 国行系统