Dart简介3--mixin

2022-09-22  本文已影响0人  逃离_102

说明

Dart 是不支持多继承的,但是它支持 mixin,简单来讲 mixin 可以 “组合” 多个类,这样就极大的减少了代码冗余。mixin是面向对象程序设计语言中的类,提供了方法的实现。其他类可以访问mixin类的方法、变量而不必成为其子类。简而言之,mixins是普通的类,我们可以从中扩展方法(或变量)而不扩展类。

示例

定义一个 Person 类,实现吃饭、说话、走路和写代码功能,同时定义一个 Dog 类,实现吃饭、和走路功能。我们定义了几个 mixin,然后通过 with 关键字将它们组合成不同的类。有一点需要注意:如果多个mixin 中有同名方法,with 时,会默认使用最后面的 mixin 的,mixin 方法中可以通过 super 关键字调用之前 mixin 或类中的方法

class Person {
  say() {
    print('say');
  }
}

mixin Eat {
  eat() {
    print('eat');
  }
}

mixin Walk {
  walk() {
    print('walk');
  }
}

mixin Code {
  code() {
    print('key');
  }
}

class Dog with Eat, Walk{}
class Man extends Person with Eat, Walk, Code{}

从用法有点类似于Java中的多接口实现,不同点在于,mixin可以有默认实现,当然Java8中也有了这个功能。

mixin之线性化

在上面的示例中,我们发现with关键字后有多个类。那么这里就产生了一个问题——如果with后的多个类中有相同的方法,那么当调用该方法时,会调用哪个类里的方法尼?由于距离with关键字越远的类会重写前面类中的相同方法,因此分为以下两种情况:

  • 如果当前使用类重写了该方法,就会调用当前类中的方法。
  • 如果当前使用类没有重写了该方法,则会调用距离with关键字最远类中的方法。
//BindingBase
abstract class BindingBase {
  void initInstances() {
    print("BindingBase——initInstances");
  }
}
//GestureBinding
mixin GestureBinding on BindingBase{
  @override
  void initInstances() {
    print("GestureBinding——initInstances");
    super.initInstances();
  }
}
//RendererBinding
mixin RendererBinding{
  @override
  void initInstances() {
    print("RendererBinding——initInstances");
    super.initInstances();
  }
}
// WidgetsBinding
mixin WidgetsBinding on BindingBase{
  @override
  void initInstances() {
    print("WidgetsBinding——initInstances");
    super.initInstances();
  }
}
//WidgetsFlutterBinding
class WidgetsFlutterBinding extends BindingBase
    with GestureBinding, RendererBinding, WidgetsBinding {
    static WidgetsBinding ensureInitialized() {
      return WidgetsFlutterBinding();
    }
}
//main
main(List<String> arguments) {
  var binding = WidgetsFlutterBinding();
  binding.initInstances();
}

WidgetsFlutterBinding中并没有重写initInstances方法,那么就以最右边重写该方法的类——WidgetsBinding为主。那么结果应该如下:WidgetsBinding——initInstances
其实结果是:
WidgetsBinding——initInstances RendererBinding——initInstances GestureBinding——initInstances BindingBase——initInstances
这是为什么尼?仔细一点就可以发现,我们在WidgetsBinding、RendererBinding及GestureBinding中都调用了父类的initInstances方法,也因此会一级一级往上调用。如果我们取消该句代码,则会终止这种调用方式。这就是线性化。

先就写这么多,下面就得边学习边总结,有什么不对的地方,欢迎留言讨论,谢谢!

上一篇下一篇

猜你喜欢

热点阅读