mixins
做为Flutter的重要特性,值得好好研究一下bash
mixins
的中文意思是混入,就是在类中混入其余功能。ide
Dart中的定义是:函数
Mixins are a way of reusing a class’s code in multiple class hierarchies.
复制代码
Mixins是一种在多个类层次结构中复用类代码的方法。post
能够看出Mixins最重要的功能是复用代码,咱们先看下JAVA,复用代码的方式有哪些:ui
继承spa
子类能够复用父类的方法和属性,可是JAVA里的继承只能单继承。code
组合对象
将要复用的代码,封装成类A,让其余类持有A的实例,看上去貌似解决了复用代码的问题,可是一方面,每一个类持有的A的实例是不一样的,有多少个类,就总共有多少个A的实例,并且另外一方面,即便A使用单例,使用起来也很不方便。继承
接口接口
定义一个接口interface,类实现interface,这样虽然接口是同一个,可是实现倒是分散的,能复用的代码是有限的。
因此在JAVA里想要复用代码,限制是不少的。
这就有了mixins
的概念,mixins
最先的根源来自于Lisp,由于Dart也受到smalltakk的影响,因此Dart引入了mixins
的概念,
在维基百科中有对mixins
最准确的定义:
在面向对象的语言中,mixins类是一个能够把本身的方法提供给其余类使用,但却不须要成为其余类的父类。
复制代码
mixins
是要经过非继承的方式来复用类中的代码。
这里举个例子,有一个类A,A中有一个方法a(),还有一个方法B,也想使用a()方法,并且不能用继承,那么这时候就须要用到mixins,类A就是mixins类(混入类),类B就是要被mixins的类,对应的Dart代码以下:
类A mixins 到 B
class A {
String content = 'A Class';
void a(){
print("a");
}
}
class B with A{
}
B b = new B();
print(b.content);
b.a();
复制代码
输出是:
A Class
a
复制代码
将类A mixins 到 B,B可使用A的属性和方法,B就具有了A的功能,可是须要强调的是:
mixins要用到的关键字 with
怎么来理解with
呢?很简单:
继承 -> extends
mixins -> with
继承和mixins是同样的,是语言的特性,with和extends是关键字。
由于mixins使用的条件,随着Dart版本一直在变,这里讲的是Dart2.1中使用mixins的条件:
看下面代码:
class A {
void a(){
print("a");
}
}
class A1 {
void a1(){
print("a1");
}
}
class B with A,A1{
}
B b = new B();
b.a();
b.a1();
复制代码
输出是:
a
a1
复制代码
可是,若是A和A1的方法相同,并且调换A和A1的顺序,在被mixins的类中实现同一个方法呢,看下面的代码:
class A {
void a(){
print("a");
}
}
class A1 {
void a(){
print("a1");
}
}
class B with A,A1{
}
class B1 with A1,A{
}
class B2 with A,A1{
void a(){
print("b2");
}
}
class C {
void a(){
print("a1");
}
}
class B3 extends C with A,A1{
}
class B4 extends C with A1,A{
}
class B5 extends C with A,A1{
void a(){
print("b5");
}
}
B b = new B();
B1 b1 = new B1();
B2 b2 = new B2();
B3 b3 = new B3();
B4 b4 = new B4();
B5 b5 = new B5();
b.a();
b1.a();
b2.a();
b3.a();
b4.a();
b5.a();
复制代码
会是什么样的结果呢?
Mixins in Dart work by creating a new class that layers the implementation of the mixin
on top of a superclass to create a new class — it is not “on the side” but “on top” of
the superclass, so there is no ambiguity in how to resolve lookups.
复制代码
以
class B3 extends C with A,A1{
}
复制代码
为例,能够分解为:
class CA = C with A;
class CAA1 = CA with A1;
class B3 extends CAA1{
}
复制代码
mixins不是多继承
Mixins is not a way to get multiple inheritance in the classical sense. Mixins is a way to abstract and reuse a family of operations and state. It is similar to the reuse you get from extending a class, but it is compatible with single-inheritance because it is linear.
复制代码
因此输出结果是:
a1
a
b2
a1
a
b5
复制代码
mixins的实例类型是什么?
很简单,mixins的类型就是其超类的子类型,因此:
B3 b3 = B3();
print(b3 is C);
print(b3 is A);
print(b3 is A1);
复制代码
都会为true
on
关键字,以前是用于try catch,用于指定异常的类型的。
此次,on
只能用于被mixins
标记的类,例如mixins X on A
,意思是要mixins X的话,得先接口实现或者继承A。这里A能够是类,也能够是接口,可是在mixins的时候用法有区别.
想看接口的请看个人这篇文章Flutter Dart语法(1):extends 、 implements 、 with的用法与区别
用继承:
lass A {
void a(){
print("a");
}
}
mixin X on A{
void x(){
print("x");
}
}
class mixinsX extends A with X{
}
复制代码
得首先实现这个接口,而后再用mix
class A {
void a(){
print("a");
}
}
mixin X on A{
void x(){
print("x");
}
}
class implA implements A{
@override
void a() {
// TODO: implement a
}
}
class mixinsX2 extends implA with X{
}
复制代码