美文网首页Flutter
Dart语法Mixin机制

Dart语法Mixin机制

作者: wtm007 | 来源:发表于2020-04-16 20:25 被阅读0次

一、概念
“Mixins are a way of reusing a class’s code in multiple class hierarchies.” 混合是一种在多个类层次结构中重用类代码的方法。
从概念上我们可以理解它是为了解决代码重用的一种方式。学习java的小伙伴可能会想到interface,Dart中的类都可以作为接口,这不是已经有了
解决方案了吗?为什么还需要mixin呢?

二、使用
首先我们来解决上面提到的问题,为什么要使用mixin。
我们很多语言都是采用了单继承+接口多实现的方式,但是这种方式不能很好的适用于所有场景。
我们看下下面这个假设的例子:

mixin_extends2.PNG
我们通过上图可以看出,这些学生都有一个共同的父类Student,然后又有三个抽象子类:文科班学生,理科班学生、艺术班学生。这些类具有相同的行为和能力,但是有的类又有自己独有的行为和能力。比如文科、理科、艺术班学生都可以上数学课程,
但是只有理科班学生可以上物理课程,文科班和艺术班学生可以上地理课程,物理班学生又不可以上地理课程。那么问题就出现了,部分具有相同能力和行为的子类都要保留一份相同的代码实现,比如文科班学生类和艺术班学生类都要实现一份上地理课的实现,
就产生了冗余。这种单继承模型下,无法把部分子类具有相同行为能力抽象到基类中,因为对其它不具有此行为的子类来说是不合适的,例如把上地理课放在基类student中,因此只能在各自子类中实现。
abstract class Student{
}

abstract class GeographyClass{
  void goGeography();
}

abstract class MathClass{
  void goMath();
}

abstract class PhysicsClass{
  void goPhysics();
}

class ScienceStudent extends Student implements MathClass, GeographyClass {
  @override
  void goGeography() {
    print("上地理课");
  }

  @override
  void goMath() {
    print("上数学课");
  }
}
class LiberalStudent extends Student implements MathClass, PhysicsClass {
  @override
  void goMath() {
    print("上数学课");
  }

  @override
  void goPhysics() {
    print("上物理课");
  }
}
class ArtStudent extends Student implements MathClass, GeographyClass {
  @override
  void goGeography() {
    print("上地理课");
  }

  @override
  void goMath() {
    print("上数学课");
  }
}

从上述实现代码中可以看出,子类中很多相同的冗余实现代码。那么我们是不是想有一种方式可以解决这种冗余问题,是的,mixin就能很好的解决这类问题。
下面是使用mixin改写后的代码:

abstract class Student{}

mixin GeographyClass{
  void goGeography() {
    print("上地理课");
  }
}

mixin MathClass{
  void goMath() {
    print("上数学课");
  }
}

mixin PhysicsClass{
  void goPhysics() {
    print("上物理课");
  }
}

class ScienceStudent extends Student with MathClass, GeographyClass {
}

class LiberalStudent extends Student with MathClass, PhysicsClass {
}

class ArtStudent extends Student with MathClass, GeographyClass {
}

改写后的代码可以发现,mixin很好得解决了代码冗余问题。它能复用类中的某个功能具体实现,而不是像接口一样需要类去实现哪些能力。因此mixin多继承模型很好解决了单继承模型带来的冗余问题。
注意:对mixin关键字的支持是在Dart 2.1 版本引入的,早期的版本使用abstract class来代替的。
其实在java8和Kotlin中为了解决代码重复冗余问题,使用了接口的default实现来解决这个问题:

interface ITest {
    default void test(){}
   }

三、线性化
mixin是线性化的,这句话如何理解呢?首先我们看下下面的例子:

mixin TA {
  void t() {
    print("TA");
  }
}

mixin TB {
  void t() {
    print("TB");
  }
}

class TC {
  void t() {
    print("TC");
  }
}

class Mix1 with TA, TB {//TB
}
class Mix2 with TB, TA {//TA
}

我们会得到如下结果:

TB
TA

此时你可能会总结得到规律,with后面多个类中有相同的方法,会调用距离with关键字最远的类中的方法。下面我们得到结论:
mixin混入类中时,Dart中的Mixins通过创建一个新类来实现,该类将mixin的实现层叠在一个超类之上以创建一个新类 ,它不是“在超类中”,而是在超类的“顶部。
声明 mixin 的顺序代表了继承链的继承顺序,声明在后面的 mixin,一般会最先执行。
接下来我们再看下面的例子:

class T {
  void fun() {
    print("A");
  }
}

mixin TA on T{
  void fun() {
    super.fun();
    cover();
    print("TA");
  }

  void cover() {
    print("cover TA");
  }
}

mixin TB on T {
  void fun() {
    super.fun();
    print("TB");
  }

  void cover() {
    print("cover TB");
  }
}

class A extends T with TA, TB {} // TB

class B extends T with TB, TA {} // TA

void main() {
  A a = A();
  a.fun();
}

按照我们刚才的理解,我们会得到如下结果:

   A
  cover TA
  TA
  TB

实际上,我们输出的结果是:

    A
    cover TB
    TA
    TB

回想我们得到的结论,在mixin继承链中,最后声明的mixin会把前面声明的相同方法覆盖掉。这时,即使我们代码中调用了TA的cover方法,实际上也会被TB类中的cover方法覆盖掉。因此最终调用的还是MB中的方法。

四、总结
我们大致总结了mixin的机制和使用,mixin 是一个强大的概念,我们可以跨越类的层次结构重用代码。在我们看Flutter源码时,经常会看到使用这个功能,我也是在看Flutter代码时,看到这个关键字然后进行补脑的。
1.Mixins并不是经典意义上获得多重继承的方法。
2.Mixins是一种抽象和复用一系列操作和状态的方式,而且生成多个中间的mixin类。
3.它是线性的,因此与单继承兼容。
4.Mixins除了继承Object外,不可以继承任何其他类; Mixins不可以定义构造方法。

相关文章

  • Dart语法Mixin机制

    一、概念“Mixins are a way of reusing a class’s code in multip...

  • Flutter - Dart语法基础及mixin

    一文了解Dart语法 我了解Dart语法就是参照上面链接文章 重点理解mixin mixin,翻译过来就是混入,个...

  • (六)Dart Classes(类)、Constructors(

    一、Object(对象) Dart 是一个面向对象编程语言。 Dart支持基于 mixin 的继承机制(多继承)。...

  • Dart mixin继承机制

    Mix:混合In: 进入,加入Mixin: 混入 mixin 声明 属于dart 2.1 加入的特性。以前版本通常...

  • Dart 基础(四)

    级别: ★☆☆☆☆标签:「Flutter 」「Dart」「Dart class」「Dart mixin」「Dar...

  • dart系列之:dart类的扩展

    简介 虽然dart中的类只能有一个父类,也就是单继承的,但是dart提供了mixin语法来绕过这样限制。 今天,和...

  • dart语法7-泛型

    dart语法1dart语法2-内置类型dart语法3-函数dart语法4-操作符dart语法5-异常dart语法6...

  • dart语法8-库

    dart语法1dart语法2-内置类型dart语法3-函数dart语法4-操作符dart语法5-异常dart语法6...

  • dart语法10-生成器

    dart语法1dart语法2-内置类型dart语法3-函数dart语法4-操作符dart语法5-异常dart语法6...

  • dart语法9-异步

    dart语法1dart语法2-内置类型dart语法3-函数dart语法4-操作符dart语法5-异常dart语法6...

网友评论

    本文标题:Dart语法Mixin机制

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