Dart(11)-mixin

本文详细介绍了Dart语言中的mixin特性,包括mixin的定义、历史演变、与继承的区别、线性化处理及限定符on的使用。mixin作为代码重用的手段,避免了多继承可能导致的菱形问题,提供了一种灵活的类功能扩展方式。通过实例展示了mixin的使用方法及其在解决类层次结构中代码复用的角色。
摘要由CSDN通过智能技术生成

一、什么是mixin

通俗的讲,mixin(mix-in)是一种新的语言特性,表面类似多继承,使用with关键字对类添加一些功能。官话mixin是在多个类层次结构中重用类代码的一种方法。mixin(mix-in)是为面向对象程序设计语言中的类提供了方法的实现。其他类可以访问mixin类的方法、变量而不必成为其子类。Mixin 的作用就是在多个类层次结构中重用类的代码,很好的解决了单继承带来的代码冗余问题。

二、Mixin历史

Dart 1.12或更低版本使用Mixin时必须继承至Object,并且不能调用super()方法。

Dart 1.13或更高版本支持继承至Object以外的类并使用Mixin,并且可以调用super.method()。这项支持仅在DartVM中默认开启,并且在标志后面的Analyzer中才能够使用。更具体地说,它位于命令行分析器中的--supermixin标志之后。它也可以在分析服务器中,在客户端可配置选项后面。Dart2js和dartdevc不支持SuperMixin。

Dart 2.1.0添加了mixin关键字,用于显式声明mixin。为了兼容起见,Dart仍然允许您混入未使用定义的类mixin。但是,这是有风险的。如果该类的作者不希望将该类用作混入,则他们可能会以打破混入限制的方式更改该类。例如,如果他们添加一个构造函数,则您的mixin将无法使用(The class 'xxx' can't be used as a mixin because it declares a constructor.)

三、理解mixin与继承

先举个栗子,我想在杏树上嫁接梨树代码如下:

void main() {
  Apricot().flower();
}
/**
 * 杏树
 */
class Apricot with Pair {
​
}
/**
 * 梨树
 * class 可以用mixin代替
 */
class Pair{
  void flower() {
    print('梨花');
  }
}

这样的话,杏树上就开了梨花。mixin可以理解成嫁接,就像是你嫁接在我身上之后,我继承了你的功能,我俩合体了,这属于捆绑的关系,并不是父子的关系。

为什么dart语言的设计者,不设计出可以多继承的语法,而要设计mixin来替代多继承,是因为多继承会导致菱形问题,所以一直都是单继承。

四、mixin的线性化

4.1 mixin之间的线性化

概述里讲到with后面如果有多个mixin,且有相同的函数,只会用离with最远的那个mixin里面的方法。即mixin的线性化。如下代码:

void main() {
  Apricot().flower();
}
/**
 * 杏树
 */
class Apricot with Pair , Peach{
​
}
/**
 * 梨树
 */
mixin Pair{
  void flower() {
    print('梨花');
  }
}
/**
 * 桃树
 */
mixin Peach{
  void flower() {
    print('桃花');
  }
}

如果本体里面如果有相同的函数,只会调用本体里面的方法。代码如下:

void main() {
  Apricot().flower();
}
/**
 * 杏树
 */
class Apricot with Pair{
  void flower() {
    print('杏花');
  }
}
/**
 * 梨树
 */
mixin Pair{
  void flower() {
    print('梨花');
  }
}

4.2 mixin与extends之间的优先级

void main() {
  Apricot().flower();
}
/**
 * 杏树
 */
class Apricot extends Peach with Pair implements Apple{
​
}
​
abstract class Apple {
  void flower();
}
​
/**
 * 桃树
 */
class Peach{
  void flower() {
    print('桃花');
  }
}
​
/**
 * 梨树
 */
mixin Pair  {
  void flower() {
    print('梨花');
  }
}

相同方法的调用顺序:本体>with>extends>implements

五、限定符on

限定符on主要是用于对mixin进行使用限定,当一个mixin后面跟着on xxClass(这里可以是类、接口、抽象类),那么使用这个mixin的宿主必须继承这个xxClass。如下:

/**
 * 果树
 */
class Fruiter {
​
}
​
/**
 * 杏树
 */
class Apricot extends Fruiter  with Pair, Peach {
​
}
​
/**
 * 桃树
 */
class Peach {
  void flower() {
    print('桃花');
  }
}
​
/**
 * 梨树
 */
mixin Pair on Fruiter {
  void flower() {
    print('梨花');
  }
}

而on又有点像extends,比如:

abstract class Super {
  void create() {
    print("Super");
  }
}
​
class Clazz implements Super {
  void create() {
    print("Create Clazz");
  }
}
​
mixin Mixin on Super {
  void create() {
    super.create();
    print("Create Mixin");
  }
}
​
class Clazzz extends Clazz with Mixin {
​
}
​
void main() {
  Clazzz().create();
}

Mixin类中可以使用super.create()函数,

六、总结

被mixin定义的类不能实例化,不能有构造器

mixin不能使用extends继续其他类

一个类可以混入多个mixin

mixin可以使用implements实现接口

使用混入mixin,这不是继承关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值