mixin

维基百科中这样定义 mixin:

In object-oriented programming languages, a Mixin is a class that contains methods for use by other classes without having to be the parent class of those other classes.(翻译:mixin 是一个普通类,可以让其他类在不继承这个类的情况下从这个类”借用”方法和变量。)

Support for the mixin keyword was introduced in Dart 2.1. Code in earlier releases usually used abstract class instead.(早期版本中的代码通常使用抽象类,也就是说 mixin 不过是一个 abstract class

Java tries to make up for this by using Interfaces, but that is not as useful or flexible as mixins.(从这个角度来讲,可以认为 mixin 是带具体实现的接口。)

Mixin 是对继承的一种功能扩展,它解决了继承带来的的基本问题,能够更优雅的重用不同类中的功能(这些类不太适合同一个类层次的结构)

小结

  • mixin 有点类似 abstract class
  • mixin 有点类似 interface
  • 不能继承 mixin
  • 可以使用 mixin, abstract class, class 来作为 mixin

定义方法

  • 用法: mixin [MixinClass] on [SuperClass]
  • 解释: [MixinClass]定义 mixin 类名, 例如:mixin Amixin {}
  • 解释: 可选关键字 on 用于限制 mixin 类的使用范围, 例如:Bmixin 类只能用于继承或者实现了 Bird那些类.

那些类到底是哪些类???

// 普通类,仅含有一个属性
class Bird{String name = "Bird";
}
// 1. 定义一个mixin类,含有属性和方法。
// !注意:在Amixin 内部有 String name=“A”,则表示,
// Amixin内部已经完全覆盖实现了上面得普通类Bird中所有属性和方法.所以 Amixin 属于 【那些类】
mixin Amixin {String name = "A";void say() {print(name);}
}// 2.定义一个mixin类,并使用on 限定 Bmixin 只允许 那些类 使用
mixin Bmixin on Bird {String name = "B";void say() {print(name);}
}// 3. 定义一个mixin类,只含有属性
// 同理,Cmixin 内部已经完全覆盖实现了上面得普通类Bird中所有属性和方法.所以 Cmixin 属于 【那些类】
mixin Cmixin {String name = "C";
}

使用方法 with 关键字后面跟上 mixin 的类名即可。

// 使用,普通类 OneBird 继承 Amixin
class OneBird with Amixin {}// 使用,普通类 TwoBird 继承 Bird ,继承Bird之后就允许继承 Bmixin
class TwoBird extends Bird with Bmixin {}// 使用,普通类 ThirdBird 继承 Bird ,继承Bird之后就允许继承 Bmixin ,同时继承Amixin, Cmixin
class ThirdBird extends Bird with Amixin, Bmixin,Cmixin {}

Tips:继承层级顺序可以理解为压栈,后继承的位于栈顶,优先访问,优先调用

void main() async {OneBird myBird1 = OneBird();print(myBird1.name); // ATwoBird myBird2 = TwoBird();print(myBird2.name); // B// 多继承示例:// 创建的实例 myBird3 使用继承能力时,先在 Cmixin 上找,然后 Bmixin -> Amixin -> Bird// 先找到哪个就只用哪个ThirdBird myBird3 = ThirdBird();print(myBird3.name); // C
}

为什么使用 Mixin?

flutter 的吉祥物 Dash非常可爱,它和另一个虚拟吉祥物QuickBird一样都喜欢在全世界飘荡,有时鹦鹉(Parrot)也会与他们俩一起玩耍。那么在 flutter 中如何对面他们进行建模?

纯子类化

这 3 个都是鸟,他们都具有相同的能力: 震翅飞行(flutter)发出鸟鸣(chirp) 。因此让这 3 个类 QuickBird(快鸟), Dash(蜂鸟), Parrot(鹦鹉) 继承自同一个鸟类(Bird),其中 快鸟 是一个很聪明的鸟,它还能 写文章(write)。当他们到处飞行时,结识了新朋友 蚊子,但蚊子不是一直鸟,它更不能不鸟鸣,只是能飞而已。因此为它创建一个额外的超类飞行动物
在接下来的旅途中还会遇到其他各种像虫子一样的昆虫飞行动物类提供震翅飞行(flutter)功能,鸟类(Bird)提供了发出鸟鸣(chirp) 的能力。接下来他们飞行到了石家庄,发现了一个人,他没有飞的能力,但是他能敲键盘,能写文章。

  • 现在问题来了,在代码中我们如果想实现这些功能,希望通过继承重用震翅飞行(flutter)发出鸟鸣(chirp)写文章(write)功能。但是我们却不能为这些鸟, 昆虫, 和 人类创建一个通用的超类。

  • 如果添加一个写文章(write)的功能到共同的超类生物中。那么所有继承生物的子类鸟和昆虫都会拥有这个能力,但是只有 快鸟人类应该有这个能力

  • 如果我们创建一个新的超类 博客作者 并且只有 快鸟人类 从中继承, 快鸟 会失去它的 **震翅飞行(flutter)**和 发出鸟鸣(chirp) 的能力。

  • 如果我们根本不创建一个通用的超类,我们将不得不分别在快鸟人类实现 **写文章(write)**的功能,这就导致了代码重复,从而违反 DRY 原则(不要重复自己)。

并且随着生态系统越来越庞大,复杂,这将使得未来更加难以维护和理解。为了解决这个问题,所以需要一种能够在不同层次类结构中重用代码的方法。首先想到的就是允许类从多个超类继承,但是多重继承伴随着 Diamond 问题


abstract class Bird {void move() {print('Bird ▶︎ The bird is moving');}
}mixin FlutterMixin on Bird {@overridevoid move() {super.move();print('FlutterMixin ▶︎ The bird is fluttering through the air');}
}
mixin SailMixin on Bird {@overridevoid move() {super.move();print('SailMixin ▶︎ The bird is sailing in the wind');}
}class QuickBird extends Bird with FlutterMixin, SailMixin {}
void main(String[] args){QuickBird bird = QuickBird();bird.move();
}

结果:

> Bird ▶︎ The bird is moving
> FlutterMixin ▶︎ The bird is fluttering through the air
> SailMixin ▶︎ The bird is sailing in the wind

何时使用 Mixin

最常见的 mixin 类:TickerProviderStateMixinSingleTickerProviderStateMixin,这两个类常用于动画。
这两个类会告诉 flutter,这一个小部件是动画的,并且这个小部件希望收到帧更新通知,
以便于 AnimationController 生成一个新知值,然后为动画的下一帧重绘小部件

mixin SingleTickerProviderStateMixin<T extends StatefulWidget> on State<T>implements TickerProvider {Ticker? _ticker;@overrideTicker createTicker(TickerCallback onTick) {// ..._ticker = Ticker(onTick,debugLabel:kDebugMode ? 'created by ${describeIdentity(this)}' : null);return _ticker!;}@overridevoid didChangeDependencies() {if (_ticker != null)_ticker!.muted = !TickerMode.of(context);super.didChangeDependencies();}// ...
}

当然还有其它运用 mixin 的示例:

  • Service locators
  • i18n (Internationalization/Localization)
  • Logging
  • etc.

缺点和危险

一旦你体验到 mixin 的魅力,就一定会爱上并极有可能滥用它,比如
class Creature with FlutterMixin, SailMixin, ReadMixin, EatMixin,....

Mixins 使得在一个类可以包含各种各样的功能。但是当一个类可以做太多的事情时,就违反了单一职责原则,很难对这个类的作用保持直观的理解。此外,从哪个 mixin 继承哪个方法可能会变得非常混乱,难以理解,并且其他开发人员可能不清楚代码的执行顺序。

测试

这段代码输出结果是什么?

class A {String getMessage() => 'A';
}
class B {String getMessage() => 'B';
}
class P {String getMessage() => 'P';
}class AB extends P with A, B {}
class BA extends P with B, A {}void main() {String result = '';AB ab = AB();result += ab.getMessage();BA ba = BA();result += ba.getMessage();print(result);
}

答案解析:
从语义上讲以上这段代码等同于:

class PA = P with A;
class PAB = PA with B;class AB extends PAB {}class PB = P with B;
class PBA = PB with A;class BA extends PBA {}

BA

------ 如果文章对你有用,感谢右上角 >>>点赞 | 收藏 <<<

flutter - mixin相关推荐

  1. Flutter 相关知识点

    1.下载sdk flutter官网:Install and run DevTools from Android Studio | Flutter 2.配置环境变量 as安装 dart和flutter插 ...

  2. Flutter中实现视图、功能和样式代码的分离(使用mixin与扩展函数)

    目录 1.引入apply函数 2.用Mixin分离Method和Style 3.总结:BMS模式 Flutter中,声明式的视图样式代码 和 命令式的业务功能代码 混合编写,造成了书写代码时结构混乱, ...

  3. Flutter 中不得不会的 mixin

    mixin 是 Dart 中非常重要的概念,对于未接触过此概念的Coder来说尤其重要,最近看源码的时候,由于对 mixin 不熟悉导致理解出现偏差,走了很多弯路,所以这篇文章介绍一下 mixin 概 ...

  4. flutter Dart Mixin后关于调用super的理解

    上代码 abstract class BaseClass {funcPrint() {print("BaseClass\n");} }mixin A on BaseClass {f ...

  5. Flutter框架分析(五)-- 动画

    Flutter框架分析分析系列文章: <Flutter框架分析(一)-- 总览和Window> <Flutter框架分析(二)-- 初始化> <Flutter框架分析(三 ...

  6. 阿里宣布开源Flutter应用框架Fish Redux!

    3月5日,闲鱼宣布在GitHub上开源Fish Redux,Fish Redux是一个基于 Redux 数据管理的组装式 flutter 应用框架, 特别适用于构建中大型的复杂应用,它最显著的特征是 ...

  7. Flutter学习之Dart语法特性

    一.前言 第一天把Flutter环境搭建了,并简单实现第运行第一个Flutter项目,感觉很不错,一些基本操作和原生体验差不多.用Flutter框架写过App项目的开发者都知道,Flutter是一个使 ...

  8. 即将开源 | 2亿用户背后的Flutter应用框架Fish Redux

    2019独角兽企业重金招聘Python工程师标准>>> 背景 在闲鱼深度使用 Flutter 开发过程中,我们遇到了业务代码耦合严重,代码可维护性糟糕,如入泥泞.对于闲鱼这样的负责业 ...

  9. 【Flutter】Dart 面向对象 ( mixins 特性 )

    文章目录 一.mixins 简介 二.mixins 判定示例 二.mixins 示例 四. 相关资源 一.mixins 简介 mixins 作用 : mixins 是 Dart 的重要特性 ; 添加特 ...

最新文章

  1. 多迪人事主管揭秘:面试官是如何面试Web前端求职者?
  2. Mac上安装hadoop
  3. 利用who,w,ps和top等指令查看linux下的进程执行情况.,UNIXLINUX操作系统实验指导书...
  4. 2017腾讯编程题----游戏人物标记
  5. h5常见问题汇总及解决方案
  6. 如何在ESXi 5.5主机上安装ESXi 5.5客户机
  7. 盘点9 个实用的 JSON 工具
  8. 【转】测试人员的思想理念和工作方法
  9. nssl1210-质数【素数筛】
  10. 网络新潮文化:Wiki不完全手册
  11. 为什么用openstack_如何为OpenStack贡献力量
  12. 2021暨南大学计算机技术上岸经验贴
  13. 简单干净的C#方法设计案例:SFCUI.AjaxValue()之二
  14. Gym - 100783E
  15. VMware workstaion上传虚拟机到VMware EXSI 5.5
  16. Neo4j数据导入与可视化
  17. Windows XP十五周年:由爱生恨的系统霸主
  18. systemd 编写微信鱼虾蟹棋牌搭建服务管理脚本
  19. pearson相关系数_pearson相关系数与典型相关性分析(CCA)
  20. 联想商务机M8000T风扇狂转解决方法

热门文章

  1. 日本房地产泡沫经验及其借鉴
  2. java性能调优(转载)
  3. 波动方程,达朗贝尔解和亥姆霍兹方程
  4. PhotoBulk for Mac v2.3 图片批量调整重命名转换水印工具
  5. Image2icon for Mac(icns图标转换制作工具)
  6. 着色Shading(1)(光照、着色)(笔记)
  7. 初学者这样玩 TypeScript,迟早进大厂系列!
  8. 关于监控摄像头小程序直播使用流程及主要应用
  9. 微信小程序(一)认识微信小程序
  10. 吕爱国倾心讲座:混合方法研究的类型与程序设计