美文网首页
Dart学习笔记4 - Mixins理解

Dart学习笔记4 - Mixins理解

作者: WizardL | 来源:发表于2019-12-09 21:00 被阅读0次

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

    当我第一次接触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的介绍,我就写到这里了吧,写的不是很好,都是我个人的理解,如果大家有问题,可以给我留言,谢谢大家的阅读与指正。

    相关文章

      网友评论

          本文标题:Dart学习笔记4 - Mixins理解

          本文链接:https://www.haomeiwen.com/subject/cxvigctx.html