热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

DartMixin要怎样理解?

会带着以下几个问题来分享mixin的相关内容什么是mixin?为什么需要mixin?怎么样使用?什么场

会带着以下几个问题来分享mixin的相关内容

  • 什么是mixin?
  • 为什么需要mixin?
  • 怎么样使用?
  • 什么场景下使用?

什么是mixin

官方:Mixins are a way of reusing a class’s code in multiple class hierarchies
mixin是在多个类层次结构中重用类代码的一种方法。 这种描述看起来跟继承没有太多的区别。我们要可以通过继承的方式从父类那得到功能的重用,但是这种方式会有这么几个问题:1、需要在多个类中实现行为,dart不支持多继承,通过lmplement实现多个接口类,无法获取到父类的实现,需要在子类内实现。2:继承会存在多重继承带来的歧义 。 下面举个例子:

Dart Mixin要怎样理解?
图片来自:https://medium.com/flutter-community/dart-what-are-mixins-3a72344011f3

我们这里有一个称为Animal的超类,它 具有三个子类(Mammal,Bird和Fish)。在底部,我们有具体的类。小方块代表行为。例如,蓝色正方形表示具有这种行为的类的实例可以游泳。

有些动物有共同的行为:猫和鸽子都可以走路,但猫不能飞(Nyan Cat except除外)。这些行为与该分类正交,因此我们无法在超类中实现这些行为。
如果一个类可以有多个超类,这很容易,我们可以创建其他三个类:WalkerSwimmerFlyer。在那之后,我们只是要继承沃克类。但是在Dart中,每个类(除外Object)都只有一个超类。除了可以从Walker类继承之外,我们可以实现它,就好像它是一个接口一样,但是我们必须在多个类中实现行为,因此这不是一个好的解决方案。实际上 走路这行为我们只需要写一遍就可以了,但是在dart中我们去使用implement来去继承多个类是,父类的方法我们是无法访问的,子类需要在实现一遍。这显然不是一个很好的方式。

多重继承歧义:当Animal里有个walk方法,Manmmal里也有walk方法,在Cat里调用super.walk()方法是就会产生歧义,无法明确调用谁的walk方法。
那么mixin是怎样解决这些问题的呢?我们先来看看mixin是怎么使用的吧

void main() {
  Dove dove = Dove();
  dove.walk();
  dove.fly();
}

abstract class Animal {}

abstract class Bird extends Animal {}

abstract class Walk {
  void walk() {
    print("Walk Walk");
  }
}

abstract class Fly {
  void fly() {
    print("Fly Fly");
  }
}

class Dove extends Bird with Walk, Fly {}

通过with关键字我们就很好的将 走,飞 两个行为”继承“过来的。那么mixin又是如何解决多重继承歧义的呢?我们来看看下面的代码:

void main() {
  Dove dove = Dove();
  dove.walk();
}

abstract class Animal {}

abstract class Bird extends Animal {}

class AnimalWalk {
  void walk() {
    print("AnimalWalk Walk");
  }
}

class PersonWalk {
  void walk() {
    print("PersonWalk Walk");
  }
}

class Dove extends Bird with PersonWalk, AnimalWalk {
  // @override
  // void walk() { // 当注释未打开是  打印为 AnimalWalk Walk,当Dove extends Bird with AnimalWalk,PersonWalk时打印为PersonWalk Walk,当子类自己重写walk时 打印为Dove walk
  //   print("Dove walk");
  // }
}

上面的例子可能不太恰当但是可以说明问题,也就在walk中最终执行谁的walk取决于 1、子类实现了walk,执行子类的 2、子类未实现,会执行with最后一个父类的walk方法。这个跟with 的顺序有关。我们可以理解为
Bird–继承—PersonWalK—继承–AnimalWalk—Dove。这个顺序,那么重写的方法的调用链就是反过来:
Dove—AnimalWalk–PersonWalK–Bird.。其实PersonWalk,AnimalWalk之间是没有关系的,但是有共同的方法,通过这种方式就能很好的重用方法,和避免调用歧义了。

使用方式 关键字顺序

extends => with => implements
class Dog extends Animal with Person implements Fly {}

mixin 修饰的类有几个限制:

  • 类不允许有构造方法
  • class 修饰的类如果想要通过with使用mixin特性,则必须是继承object的对象
  • 进行mixin的类他们必须有同一个Superclass
  • mixin 修饰的类可以使用 on 关键字来进行继承操作(如下:)
   void thinking() {
     print("person thinking");
   }
 }
 
 mixin A on Person {
   void thinking() {
 //    super.thinking();
     print("A thinking");
   }
 }
 mixin B on Person {
   void thinking() {
     super.thinking();
     print("B thinking");
   }
 } 

与extends的区别

  • 1)extends 方法必须有依赖顺序, mixin本身没有
  • 2)extends 的类型只与直接直系关系有关 , mixin 满足 extends , with , implements 的所有类型
  • 3)mixin的实现方式将减少无用的由于extends或者implements所产生的无用代码
  • 4)dart中实现mixin概念使用的是extends的方式,但两者的设计理念完全不是一回事

注意点

  • 1)通过mixin想要达到约束使用顺序的能力,必须要遵循mixin的继承链顺序
  • 2)mixin使用的前提是统一超类

什么情况下会使用它

  • 1)如果遇到需要继承多个父类达到使用方法的目的, 此时可以使用 mixin
  • 2)当代码复用的情况不适合使用 继承,工具类的时候也可以考虑使用mixin

flutter中的典型使用

  • widget 的父类 DiagnosticableTree
  • class WidgetsFlutterBinding extends BindingBase with GestureBinding, ServicesBinding, SchedulerBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding
    以上就是mixin的内容,欢迎拍砖,交流!

推荐阅读
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 开源Keras Faster RCNN模型介绍及代码结构解析
    本文介绍了开源Keras Faster RCNN模型的环境需求和代码结构,包括FasterRCNN源码解析、RPN与classifier定义、data_generators.py文件的功能以及损失计算。同时提供了该模型的开源地址和安装所需的库。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • Flutter 布局(四) Baseline、FractionallySizedBox、IntrinsicHeight、IntrinsicWidth详解
    本文主要介绍Flutter布局中的Baseline、FractionallySizedBox、IntrinsicHeight、IntrinsicWidth四种控件,详细介绍了其布局 ... [详细]
  • 第五章:集合01
    第三章:集合01一:集合的框架结构图1.集合和数组的区别:2.Collection集合的方法:publicclassCol ... [详细]
  • 注:根据Qt小神童的视频教程改编概论:利用最新的Qt5.1.1在windows下开发的一个小的时钟程序,有指针与表盘。1.Qtforwindows开发环境最新的Qt已经集 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 查找给定字符串的所有不同回文子字符串原文:https://www ... [详细]
  • Opencv提供了几种分类器,例程里通过字符识别来进行说明的1、支持向量机(SVM):给定训练样本,支持向量机建立一个超平面作为决策平面,使得正例和反例之间的隔离边缘被最大化。函数原型:训练原型cv ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有