Dart的mixin详解

简介: Dart的mixin详解

mixin 是什么?

Mixin 是一种在多个类层次结构中重用代码的方法。它是Dart里的新特性。

mixin的用途

mixin是面向对象程序设计语言中的类,提供了方法的实现。其他类可以访问mixin类的方法、变量而不必成为其子类。Mixin的作用就是在多个类层次结构中重用类的代码,在类中混入其他功能,来增强代码的复用能力。

你可以将多个mixins放入同一个类中,而且dart对这个数量没有作任何限制。


mixin的使用

使用with关键字将mixin加入到class中。用一个很简单的例子来说明其使用方法:


1、声明

声明一个mixin

mixin Eat {
    void eat() {
        print('eating');
    }
}
mixin Speak {
    void speak() {
        print('speaking');
    }
}

2、混入到类中(使用with关键字)

abstract class Animal {
    void breath() {
        print('breath');
    }
}
class People extends Animal with Eat Speak  {
}

People这个类继承自Animal类但是混入了Eat和Speak。People 这个类就有了Eat和Speak的属性。


mixin的使用注意事项

作为mixins的类只能继承自Object,不能继承其他类

作为mixins的类不能有构造函数

mixin的深入了解

可以使用关键字 on 来指定哪些类可以使用该 Mixin 类。

当声明一个 mixin 时,on后面的类是使用这个mixin的父类约束。也就是说一个类若是要 with 这个 mixin,则这个类必须继承或实现这个 mixin 的父类约束。

比如有 Mixin 类 A,但是 A 只能被 B 类使用,则可以这样定义 A:

class Musician {
  // ...
}
mixin MusicalPerformer on Musician {
  // ...
}
class SingerDancer extends Musician with MusicalPerformer {
  // ...
}

在这个例子中,只有扩展或实现音乐家类的类才能使用mixin MusicalPerformer。


mixin 的顺序决定了同名方法的调用关系

它类似于扩展类所获得的重用,但它与单继承兼容,因为它是线性的。线性化决定了每次执行的是最上层超类的方法。

原理告诉我们一个非常重要的事情:声明mixins的顺序决定了继承链,即决定了最上层到底层的超类(superclass)的排序。mixin 可以理解为对类的一种“增强”,但它与单继承兼容,因为它的继承关系是线性的。


简单来说with 后面的类会覆盖前面的类的同名方法。看下面这个例子

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() {
  String result = '';
  AB ab = AB();
  result += ab.getMessage();
  BA ba = BA();
  result += ba.getMessage();
  print(result);
}

结果是:BA


class A {
  printMessage() => print('A');
}
mixin B on A {
  printMessage() {
    super.printMessage();
    print('B');
  }
}
mixin C on B {
  printMessage() {
    super.printMessage();
    print('C');
  }
}
class D with A, B, C {
  printMessage() => super.printMessage();
}
void main() {
  D().printMessage();
}

输出结果:

A

B

C


在看下面这个例子

class A {
  printMessage() => print('A');
}
class B {
  printMessage() => print('B');
}
mixin C on A {
  printMessage() {
    super.printMessage();
    print('C');
  }
}
class D with A, B, C {
  printMessage() => super.printMessage();
}
void main() {
  D().printMessage();
}

结果是:

B

C


是不是以为是

A

C


为什么是B C不是A C 呢?

根据前面说的线性关系,D().printMessage()调用的是mixin C中的方法,C中调用super.printMessage() 时,super应该是class D with A, B,所以C中的调用的super.printMessage() 其实是调用的B中的printMessage方法。


思考题

abstract class A {
  void method() {
    print("I am A");
  }
}
class B extends A{ 
  void method() {
    print("I am B");
  }
}
mixin Mixin on A {
  void method() {
    super.method();
    print("Mixin");
  }
}
class Test extends B with Mixin {}
void main() {
    Test cli = new Test();
    cli.method();
}


结果是什么?


答案

I am B

Mixin




相关文章
Kali 换源(国内优质镜像源地址)2023最新
Kali 换源(国内优质镜像源地址)2023最新
4858 0
|
消息中间件 JavaScript Dubbo
spring cloud alibaba 组件版本关系 以及 毕业版本依赖关系
spring cloud alibaba 组件版本关系 以及 毕业版本依赖关系
793 0
|
5月前
|
人工智能 前端开发 JavaScript
从代码中诞生的浪漫:一个程序员的表白艺术
本文介绍了一款用代码表达爱意的表白网页项目,通过JavaScript、HTML5和CSS3技术实现。它不仅是一个简单的网页,更是一段爱情诗、情感载体和个人魅力展示。借助CodeBuddy智能助手,项目实现了动态页面效果、多媒体展示和互动游戏等功能,支持多设备兼容与性能优化。开源分享旨在激发创意,未来还将拓展多语言支持和社区模块,证明代码也能编织浪漫。
215 19
|
弹性计算 容灾 关系型数据库
阿里云服务器ECS中扩容云盘后磁盘容量没有增加的解决方法
ECS控制台操作扩容只是扩大云盘的存储容量,不会扩容ECS实例的文件系统。还需要登录实例,然后进行扩容文件系统的操作。
2053 0
阿里云服务器ECS中扩容云盘后磁盘容量没有增加的解决方法
|
5月前
|
JSON JavaScript API
MCP 实战:用配置与真实代码玩转 GitHub 集成
MCP 实战:用配置与真实代码玩转 GitHub 集成
1222 4
|
11月前
|
搜索推荐 Java 数据库
打造个性化安卓启动器:从概念到实现##
【10月更文挑战第40天】 在数字时代,智能手机不仅是通讯工具,更是个性展示的窗口。本文将带你了解如何打造一个独一无二的安卓启动器,让你的手机界面与众不同,并提升你的开发技能。 ##
226 18
|
10月前
|
Shell 数据安全/隐私保护
|
11月前
|
机器学习/深度学习 数据采集 数据处理
Scikit-learn Pipeline完全指南:高效构建机器学习工作流
Scikit-learn管道是构建高效、鲁棒、可复用的机器学习工作流程的利器。通过掌握管道的使用,我们可以轻松地完成从数据预处理到模型训练、评估和部署的全流程,极大地提高工作效率。
210 2
Scikit-learn Pipeline完全指南:高效构建机器学习工作流
|
11月前
|
Docker 容器
docker 修改容器内的系统时间
【10月更文挑战第27天】docker 修改容器内的系统时间
2961 2
STM32CubeMX WS2812B灯驱动
STM32CubeMX WS2812B灯驱动
899 1