Void-7's

Dart基础:Mixin线性化图解

当您将mixin混入类中时,请记住下面这句话:

'Dart中的Mixins通过创建一个新类来实现,该类将mixin的实现层叠在一个超类之上以创建一个新类 ,它不是“在超类中”,而是在超类的“顶部”,因此如何解决查找问题不会产生歧义。

— Lasse R. H. Nielsen on StackOverflow.'

1

在AB和P之间创建新类,这些新类是超类P与A类和B类之间的混合类。

正如你所看到的那样,我们并没有使用多重继承!

  • Mixins不是一种在经典意义上获得多重继承的方法。
  • Mixins是一种抽象和重用一系列操作和状态的方法。
  • 它类似于扩展类所获得的重用,但它与单继承兼容,因为它是线性的。

— Lasse R. H. Nielsen on StackOverflow.

声明mixins的顺序代表了从最高级到最高级的继承链,这件事非常重要,你需要记住。

mixin应用程序实例的类型是什么?

通常,它是其超类的子类型,也是mixin名称本身表示的类的子类型,即原始类的类型。 — dartlang.org

所以这意味着这个程序

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() {
  AB ab = AB();
  print(ab is P);
  print(ab is A);
  print(ab is B);

  BA ba = BA();
  print(ba is P);
  print(ba is A);
  print(ba is B);
}

将在控制台中打印六行true。

🙄什么时候应该使用mixins?

当我们想要在不共享相同类层次结构的多个类之间共享行为时,或者在超类中实现此类行为没有意义时,Mixins非常有用。

📈Mixins的规范正在发展

如果你对Dart语言的演变感兴趣,你应该知道它的规范将在Dart 2.1中发展,他们会喜欢你的反馈。 有关详细信息,请阅读此内容

为了让您了解未来的一些趋势,请考虑以下源代码:

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

class MySuper implements Super {
  void method() {
    print("MySuper");
  }
}

mixin Mixin on Super {
  void method() {
    super.method();
    print("Sub");
  }
}

class Client extends MySuper with Mixin {}

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

第13行到第18行的mixin声明表示Super上的超类约束。 这意味着为了将这个mixin用在这里,这个类必须继承或实现Super,因为mixin使用了Super提供的功能。

这个程序的输出是:

如果你想知道为什么,请回忆mixins是如何线性化的:

img

第15行调用super.method()实际上调用了第8行声明的方法。

🐬完整的 Animal example

你可以在下面找到我用它介绍mixins的完整示例:

abstract class Animal {}

abstract class Mammal extends Animal {}

abstract class Bird extends Animal {}

abstract class Fish extends Animal {}

abstract class Walker {
  // This class is intended to be used as a mixin, and should not be
  // extended directly.
  factory Walker._() => null;

  void walk() {
    print("I'm walking");
  }
}

abstract class Swimmer {
  // This class is intended to be used as a mixin, and should not be
  // extended directly.
  factory Swimmer._() => null;

  void swim() {
    print("I'm swimming");
  }
}

abstract class Flyer {
  // This class is intended to be used as a mixin, and should not be
  // extended directly.
  factory Flyer._() => null;

  void fly() {
    print("I'm flying");
  }
}

class Dolphin extends Mammal with Swimmer {}

class Bat extends Mammal with Walker, Flyer {}

class Cat extends Mammal with Walker {}

class Dove extends Bird with Walker, Flyer {}

class Duck extends Bird with Walker, Swimmer, Flyer {}

class Shark extends Fish with Swimmer {}

class FlyingFish extends Fish with Swimmer, Flyer {}

我们可以在下面看到这些mixin是如何线性化的:

img

出处:https://www.jianshu.com/p/a578bd2c42aa