小白都能看懂的关于mixins机制的理解(代码片段)

Beason_H Beason_H     2023-01-18     147

关键词:

前言

​ 在学习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 
  @override
  initInstances() 
    super.initInstances();
    print('B');
  


mixin C on BaseA 
  @override
  initInstances() 
    super.initInstances();
    print('C');
  


mixin D on BaseA 
  @override
  initInstances() 
    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 
  @override
  initInstances() 
    super.initInstances();
    print('ABinding.initInstances()');
  


mixin BBinding on BindingBase 
  @override
  initInstances() 
    super.initInstances();
    print('BBinding.initInstances()');
  


mixin CBinding on BindingBase 
  @override
  initInstances() 
    super.initInstances();
    print('CBinding.initInstances()');
  


class WidgetsFlutterBinding extends BindingBase
    with ABinding, BBinding, CBinding 
  static void ensureInitialized() 
    WidgetsFlutterBinding();
  


void main() 
  WidgetsFlutterBinding.ensureInitialized();

欢迎评论区给出答案讨论

小白都能看得懂的教程一本教你如何在前端实现富文本编辑器(代码片段)

小白都能看得懂的教程一本教你如何在前端实现富文本编辑器博主博客文章内容导航(实时更新)更多优质文章推荐:收藏!最详细的Python全栈开发指南看完这篇你还不会Python全栈开发你来打我!!!一本教你如何在... 查看详情

小白都能看懂的实战教程手把手教你pythonweb全栈开发(day4)(代码片段)

大家好,我叫亓官劼(qíguānjié),这个《小白都能看懂的实战教程手把手教你PythonWeb全栈开发》是一个零基础的实战教程,手把手带你开发一套系统,带你了解Pythonweb全栈开发,目前正在连续更新中,... 查看详情

小白都能看懂的实战教程手把手教你pythonweb全栈开发(day2)(代码片段)

小白都能看懂的实战教程手把手教你PythonWeb全栈开发Flask(PythonWeb)实战系列之在线论坛系统第二讲这是小白都能看懂的实战教程手把手教你PythonWeb全栈开发的第二讲,如果文中有基础知识不太熟悉的话,可以看博主前几期... 查看详情

[图解]小白都能看懂的fasterr-cnn–原理和实现细节(代码片段)

Contents [hide]1 论文原文2 介绍3 Anchors3.1 如何确定一个anchor是正样本还是负样本?4 实现细节5 调试信息6 参考资料论文原文FasterR-CNN:TowardsReal-TimeObjectDetectionwithRegionProposalNetworks介绍  FasterRCNN由RossB.Girshick在2016年提出ÿ 查看详情

彻底理解volatile关键字及应用场景,面试必问,小白都能看懂!(代码片段)

来源:blog.csdn.net/fumitzuki/article/details/81630048volatile关键字是由JVM提供的最轻量级同步机制。与被滥用的synchronized不同,我们并不习惯使用它。想要正确且完全的理解它并不容易。Part1Java内存模型Java内存模型由Java虚拟机规范定... 查看详情

小白都能看懂的实战教程手把手教你pythonweb全栈开发(day5)(代码片段)

大家好,我叫亓官劼(qíguānjié),这个《小白都能看懂的实战教程手把手教你PythonWeb全栈开发》是一个零基础的实战教程,手把手带你开发一套系统,带你了解Pythonweb全栈开发,目前正在连续更新中,... 查看详情

小白都能看懂的实战教程手把手教你pythonweb全栈开发(day6)(代码片段)

大家好,我叫亓官劼(qíguānjié),这个《小白都能看懂的实战教程手把手教你PythonWeb全栈开发》是一个零基础的实战教程,手把手带你开发一套系统,带你了解Pythonweb全栈开发,目前正在连续更新中,... 查看详情

小白都能看懂的linux安装oracle数据库详细教程(代码片段)

作者简介作者:LuciferLiu,中国DBA联盟(ACDU)成员。目前主要从事OracleDBA工作,曾从事Oracle数据库开发工作,主要服务于生产制造,汽车金融等行业。现拥有OracleOCP,OceanBaseOBCA认证,擅长Oracle数据库运维... 查看详情

图解连狗子都能看懂的python基础总结!(代码片段)

介绍在这篇文章中,我写了关于机器学习和DeepLerning用户的Python编程基础知识我以初学者容易理解的方式进行了说明,如果你有任何问题,请评论。本文所介绍的"Python基础知识"的总体情况是这样的。什么是变量... 查看详情

实战篇:小白都能看懂的linux安装oracle数据库详细教程(代码片段)

作者简介作者:LuciferLiu,中国DBA联盟(ACDU)成员。目前主要从事OracleDBA工作,曾从事Oracle数据库开发工作,主要服务于生产制造,汽车金融等行业。现拥有OracleOCP,OceanBaseOBCA认证,擅长Oracle数据库运维... 查看详情

小白都能看懂的sql零基础入门,一文带你轻松学会增删改查!(代码片段)

作者简介作者:LuciferLiu,中国DBA联盟(ACDU)成员。目前从事OracleDBA工作,曾从事Oracle数据库开发工作,主要服务于生产制造,汽车金融等行业。现拥有OracleOCP,OceanBaseOBCA认证,擅长Oracle数据库运维开发&#... 查看详情

小白都能看得懂的教程看完这篇还不会生成随机验证码图片,你来打我!!!(代码片段)

小白都能看得懂的教程一文教你实现生成随机图像验证码大家好,我叫亓官劼(qíguānjié),三本计算机在读,目前在积极准备21计算机考研中,同时也在学习后端开发,准备工作。不敢孤注一掷,... 查看详情

小白都能看懂的linux系统下安装配置zabbix

实验环境:操作系统:Centos7.6服务器ip:192.168.10.100运行用户:root网络环境:InternetZabbix是一个基于web界面的提供分布式系统监控及网络功能的企业级的开源监控工具,做为一个企业运维人员来说,zabbix可以给企业和运维人员带来... 查看详情

小白也能看懂的插件化droidplugin原理--反射机制和hook入门

  前言:在上一篇博文《小白也能看懂的插件化DroidPlugin原理(一)--动态代理》中详细介绍了DroidPlugin原理中涉及到的动态代理模式,看完上篇博文后你就会发现原来动态代理真的非常简单,只不过就是实现一个InvocationHandler... 查看详情

小白都能看懂的redis讲解--针对单个键操作集锦

1重命名键renamekeynewname可以对键重命名,下面的例子我们创建了一个key为name,value为luke的键值对。然后将name重命名为user,之后查询name就返回nil,而user是可以查到值的。127.0.0.1:6379>setnamelukeOK127.0.0.1:6379>getname"luke"127.0.0.1:6379&... 查看详情

小白都能看懂的分布式事务与2pc

2PC通信原理分布式事务的原子性什么是2PC2PC提交事务的过程2PC的全局提交规则2PC通信架构集中式2PC通信架构分层2PC通信架构线性2PC通信架构故障恢复站点故障报文丢失总结分布式事务的原子性一提到到事务,一般就会想到它... 查看详情

小白也能看懂的dfs算法本质详解(代码片段)

DFS算法的本质引言DFS俗称深搜,是一种常见的算法模型我们通过借助函数递归和递归停止条件的运用实现对数据的高级枚举对于DFS算法而言,最重要的是如何去枚举数据,即如何去搜索?这是在运用DFS之前我们就应该思考的问题... 查看详情

猴子都能看懂的androidmenu总结(代码片段)

简单谈谈Androidmenu菜单的使用,帮助入门的同学。menu主要分类:选项菜单:最常规的菜单子菜单:多层菜单的实现方案之一上下文菜单:android中长按视图控件后出现的菜单选项菜单(OptionMenu)该菜单默认在右上... 查看详情