Dart学习笔记4 - Mixins理解

今天应做的事没有做,明天再早也是耽误了。——裴斯泰洛齐

当我第一次接触Mixin的概念的时候,我是很茫然的,因为我之前一直都是使
用kotlin或者是java的语言开发项目的,这个知识点在这两种语言中根本是不存在的。不过,直到我开始使用它的时候,我才意识到它的强大。

为什么我们需要Mixin的特性呢?


如上这张图片很好理解,类比java来看呢,就是一个extends关系图。简单的介绍下,动物这个class有三个子类别,分别是鱼类,鸟类及哺乳动物,再继续就是各个类别的子类了。

哺乳动物的特性,鸟类的特性,鱼的特性,我们总结归纳下就是:哺乳,fly ,swim;既然是特性,我想,java的表示方式肯定是implement interface了,而每层与每层类别之间的关系,自然就是extends calss了。

哺乳动物中有具体的三种生物,那我抽象他们的特质为breast,而bird的特质就是fly,鱼就是swim吧。如果我们使用interfac的实现方式,那么我们需要每个具体的子类都去实现这个interface。而我们已经定义好了mammal,bird以及fish,假设,我们在他们中已经定义好了各自的方法,breast,fly和swim,那么,你们想想,我再去imple interface是不是就显得有点多余了呢?是不是现在代码很繁重呢?回答是,是的。那如何解决这种问题呢?

使用Mixin特性解决code reuse提升代码的简洁和层次感

Mixins are a way of reusing a class’s code in multiple class hierarchies.
**— ** dartlang.org

上面的问题我们自然要使用Mixin来进行解决了,写下简单的代码逻辑

class Animal{
}

class Mammal{
	…
	void breast();
}

class Bird{
	…
	void fly();
}

class Fish{
	…
	void swim();
}

class Dolphin extends Animal with Mammal
{}
Class Bat extends Animal with Mammal
{}
class Cat extends Animal with Mammal
{}
…

上面的示例中,我们可以发现我们reuse了Mammal Bird Fish类。这样我们就可以免去了定义接口interface的代码。是不是简洁了很多呢?

Mixin的一些约束

The mixin feature comes with a few restrictions (from dartlang.org ):

  • Dart 1.12版本或者更低的版本如果想要支持mixins,那么它必须继承object,同时,禁止调用super的方法。

  • Dart 1.13或更高版本支持可以从Object以外的类扩展的mixin,并且可以调用super.method()。默认情况下,仅在Dart VM和分析器中的标志后面提供此支持。更具体地说,它位于命令行分析器中的—supermixin标志的后面。它也可以在分析服务器中的客户端可配置选项后面使用。
    Dart2js和dartdevc不支持超级混合。

  • 在Dart 2.1中,mixin的限制较少。
    例如,Flutter支持mixins调用super()并从Object以外的其他类进行扩展,但是语法有望在出现在所有Dart SDK中之前发生变化。
    有关详细信息,[](sdk/mixin-declaration.md at master · dart-lang/sdk · GitHub)

基于以上几点,总结下来,一个mixin类的样子大致应该是这样的:

class A {
	void behavior();
}

这个类就是一个mixin,通俗的讲,就是继承自object同时,没有调用super.method()。

如果我们想要阻止一个类被当作mixin调用,该如何操作呢?可以这样做:

class A{
	factory A._()=> null;//这是一个命名构造方法
	void behavior();
}

Mixin行为或者特质覆盖的问题

通过以上的介绍,基本mixin的使用差不多就要结束了,但是,我这里还是要赘述一点需要大家谨慎对待的问题。我直接上代码吧!

void main() {
  String result = '';

  AB ab = AB();
  result += ab.getMessage();

  BA ba = BA();
  result += ba.getMessage();

  print(result);
}

class AB extends P with A,B{
  
}
class BA extends P with B,A{
  
}
class P{
  String getMessage()=> 'P';
}

class A{
  String getMessage()=> 'A';
}

class B{
  String getMessage()=> 'B';
}

大家可以猜想下这段代码的运行结果,这段代码A,B类以及P类中都有共同的方法getMessage(),他们分别会输出不同的值。AB,BA类分别with A,B和with B,A,最终的结果,我可以公布出来,是BA。大家想下,为什么会有这样的结果呢?

这里其实涉及到with的属性行为覆盖的问题,大家应该发现了顺序在这里是起到了关键的影响作用。是的,在不同的类中包含相同的属性行为的时候,extends或者implements中的属性行为会被with中的覆盖。而with如果mixin了多个类的时候,以最后的一个对象中的属性行为为最终的行为输出结果。

总结:关于mixin的介绍,我就写到这里了吧,写的不是很好,都是我个人的理解,如果大家有问题,可以给我留言,谢谢大家的阅读与指正。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值