Dart的mixin简明讲解

1,156 阅读2分钟

kevinwu.cn/p/ae2ce64 上面这篇文章讲得很好,我总结一下。

如果class继承或者实现了多个类,同一个方法调用的时候,实际使用的是哪个方法优先级如下with>extend>implements,如果with后面跟了多个类,后面的优先级大于前面的。

增加一种情况,代码如下:

abstract class Super {
  void method() {
    print("Super");
  }
}

class MySuper implements Super {
  void method() {
    print("MySuper");//第8行
  }
}

mixin MyMixin on Super {
  void method() {
    super.method();//第15行
    print("Sub");
  }
}

class Client extends MySuper with MyMixin {}

void main() {
  Client().method();
}

这种情况应该输出什么呢? 会输出

MySuper
Sub

MyMixin on Super意思是限定子类必须继承或实现Super,因为MyMixin使用了Super提供的功能。

第15行调用super.method()会先查找MyMixin中有没有对应的方法,发现有该方法,然后因为MyMixin限定子类必须继承或实现Super,所以第15行方法中的super.method()会调用MyMixin的子类所extend的父类的method方法,在这里就是MySupermethod()方法,所以输出MySuper,然后输出Sub

然后把代码修改一下,搞复杂点

abstract class Super {
  void method() {
    print("Super");
  }
}

class MySuper implements Super {
  void method() {
    print("MySuper"); //第9行
  }
}

mixin MyMixin1 on Super {
  void method() {
    super.method(); //第15行
    print("MyMixin1");
  }
}

mixin MyMixin2 on Super {
  void method() {
    super.method(); //第22行
    print("MyMixin2");
  }
}

class Client extends MySuper with MyMixin1, MyMixin2 {}

void main() {
  Client().method();
}

这次你觉得能输出什么? 答案是

MySuper
MyMixin1
MyMixin2

原因如下:

  1. Dart先找MyMixin2有没有method方法,发现有,就调用,然后22行会查找最后一个继承了Super的类,会找到MyMixin1的method方法
  2. MyMixin1再次寻找最后一个继承了Super的类,会找到MySuper
  3. 然后调用MySuper的method方法,输出MySuper
  4. 然后输出MyMixin1
  5. 再输出MyMixin2

理解mixin有个重要的一点,就是不要看到mixin类方法里的super就觉得是调用这个mixin类的父类的方法,mixin里的on不仅代表这个mixinon后面的子类,也是一种约束关系,限定子类也必须继承on后面的类。

拿上面的代码举例,MyMixin2 on Super意思是你如果想继承MyMixin2就必须是Super的子类才可以,然后看到MyMixin2里调用的super.method()方法,应该在Client的继承关系里从后往前查找第一个Super的子类,发现MyMixin1符合条件并且也有method方法,然后就会调用MyMixin1method方法。这样就能理解mixin的用法了。