dart mixins_Dart中的Mixins简介

news/2024/7/5 6:14:23

dart mixins

Some of the best reasons for using object-oriented programming (OOP) are its techniques for helping to keep our code clean and DRY. We’re going to explore some of Dart’s strategies for making your code reusable over separate classes.

使用面向对象编程(OOP)的一些最佳原因是其有助于保持代码干净和DRY的技术。 我们将探讨Dart的一些策略,以使您的代码可在单独的类中重用。

问题 (The Problem)

Imagine we have two creature classes, each of them with their own set of behaviors. The obvious solution would be to just directly outline the methods for each class as we need them, but many classes aren’t going to be entirely unique and will share a lot of commonality with each other. We obviously want to find the most efficient structure for writing these classes in the most reusable way.

想象一下,我们有两个生物类别,每个生物类别都有自己的一套行为。 显而易见的解决方案是根据需要直接为每个类直接概述方法,但是许多类并不是完全唯一的,并且会彼此共享许多共性。 我们显然希望找到最有效的结构,以最可重用的方式编写这些类。

Our animals will have a few specific actions they can perform and a larger behavior composed out of them. As you can see, their diet may be different, but the methods are mostly the same and should ideally be broken out into something more reusable.

我们的动物将执行一些特定的动作,并由此产生更大的行为。 如您所见,它们的饮食可能有所不同,但方法大致相同,理想情况下应分解为更可重复使用的方法。

main.dart
main.dart
class Alligator {
  void swim() => print('Swimming');
  void bite() => print('Chomp');
  void crawl() => print('Crawling');
  void hunt() {
    print('Alligator -------');
    swim();
    crawl();
    bite();
    print('Eat Fish');
  }
}

class Crocodile {
  void swim() => print('Swimming');
  void bite() => print('Chomp');
  void crawl() => print('Crawling');
  void hunt() {
    print('Crocodile -------');
    swim();
    crawl();
    bite();
    print('Eat Zebra');
  }
}

main() {
  Crocodile().hunt();
  Alligator().hunt();
}

// Output should be 
// Crocodile -------
// Swimming
// Crawling
// Chomp
// Eat Zebra
// Alligator -------
// Swimming
// Crawling
// Chomp
// Eat Fish

扩展名 (Extensions)

The most common option we have is extensions, where we can take the properties and methods on one class and make them available in another. Since we wouldn’t use Reptile in its own instance, we can set it as an abstract class so it can’t be initialized, just extended.

我们最常用的选项是扩展,在扩展中,我们可以将一个类的属性和方法用作另一个类的属性和方法。 由于我们不会在自己的实例中使用Reptile ,因此可以将其设置为抽象类,这样就无法对其进行初始化,只能对其进行扩展。

main.dart
main.dart
abstract class Reptile {
  void bite() => print('Chomp');
  void swim() => print('Swimming');
  void crawl() => print('Crawling');
  void hunt() {
    print('${this.runtimeType} -------');
    swim();
    crawl();
    bite();
  }
}

class Alligator extends Reptile {
    // Alligator Specific stuff...
}

class Crocodile extends Reptile {
    // Crocodile Specific stuff...
}

main() {
  Crocodile().hunt('Zebra');
  Alligator().hunt('Fish');
}

混合蛋白 (Mixins)

That’s nice for our current example, but as we added more animals it would quickly become evident that many of theses methods aren’t just for Reptiles. If we wanted to create a Fish class with a swim method, instead of just extending Reptile, which is very limiting when we need more functionality from other classes, since we can only use extends one per class. We can use mixins to break our more universal behaviors into smaller, more reusable components that we can add to whatever class we need them in.

这对于我们当前的示例很好,但是随着我们添加更多动物,很快就会发现许多这样的方法不仅适用于爬行动物。 如果我们想使用游泳方法创建Fish类,而不仅仅是扩展Reptile ,这在我们需要其他类的更多功能时非常有局限性,因为我们只能为每个类使用一个extends 。 我们可以使用mixin将更通用的行为分解为更小,更可重用的组件,这些组件可以添加到所需的任何类中。

We just need to use the mixin type to store our methods and use the with keyword on every class we want it included in. Unlike extends, we can add as many mixins as we want to a class.

我们只需要使用mixin类型来存储我们的方法,并在每个要包含它的类上使用with关键字。与extends不同,我们可以向一个类中添加任意数量的mixin。

main.dart
main.dart
mixin Swim {
  void swim() => print('Swimming');
}

mixin Bite {
  void bite() => print('Chomp');
}

mixin Crawl {
  void crawl() => print('Crawling');
}

abstract class Reptile with Swim, Crawl, Bite {
  void hunt(food) {
    print('${this.runtimeType} -------');
    swim();
    crawl();
    bite();
    print('Eat $food');
  }
}

class Alligator extends Reptile {
  // Alligator Specific stuff...
}

class Crocodile extends Reptile {
  // Crocodile Specific stuff...
}

class Fish with Swim, Bite {
  void feed() {
    print('Fish --------');
    swim();
    bite();
  }
}

main() {
  Crocodile().hunt('Zebra');
  Alligator().hunt('Fish');
  Fish().feed();
}

(On)

The last trick we have is the ability to do something that I like to think about as a reverse-extension. We can create a mixin that utilizes the methods from a class, which we can then use with each subclass.

我们拥有的最后一个技巧是能够做一些我想考虑为反向扩展的事情。 我们可以创建一个混合类,该混合类利用类中的方法,然后将其与每个子类一起使用。

If we wanted to break Hunt into its own mixin, we can use the on keyword to tell it that it will only be used on the Reptile class, which will give it access to all of its functionality, like our Swim, Crawl, and Bite mixins.

如果我们想将Hunt分解成自己的mixin,可以使用on关键字告诉它只能在Reptile类上使用,这将使它可以使用其所有功能,例如SwimCrawlBite mixins。

This configuration should have the exact same output as our first one.

此配置应具有与第一个配置完全相同的输出。

main.dart
main.dart
mixin Hunt on Reptile {
  void hunt(food) {
    print('${this.runtimeType} -------');
    swim();
    crawl();
    bite();
    print('Eat $food');
  }
}

abstract class Reptile with Swim, Crawl, Bite {}

class Alligator extends Reptile with Hunt {
  // Alligator Specific stuff...
}

class Crocodile extends Reptile with Hunt {
  // Crocodile Specific stuff...
}

结论 (Conclusion)

With the growing popularity of Flutter, it’s a good idea to get a good foundational understanding of the basics of the Dart programming language. Hopefully this was a helpful introduction into clarifying some of the mysteries around reusing Dart classes.

随着Flutter的日益普及,对Dart编程语言的基础知识有一个很好的基础理解是一个好主意。 希望这对阐明有关重用Dart类的奥秘有帮助。

翻译自: https://www.digitalocean.com/community/tutorials/dart-mixins

dart mixins


http://www.niftyadmin.cn/n/3649625.html

相关文章

[J2ME]RSSOwlMidlet(RSS无线阅读器)设计说明

郑昀ultrapower产品名称产品版本Keyword: RssReader RssFeed Channel j2me midp midlet kxml xmlpull RMS RssOwl java RSS无线阅读器0.7.1729[J2ME][开源]RSSOwlMidlet(RSS无线阅读器)设计说明我的RssReader资源:1:《[J2ME]RSSOwlMidlet(RSS无线阅读器…

Android项目实战系列—基于博学谷(七)课程模块(上)

由于这个模块内容较多,分为上、中、下 三篇博客分别来讲述,请耐心阅读。 课程模块分为四个部分 课程列表 课程详情 视频播放 播放记录 课程模块(上)主要讲述课程列表部分 一、水平滑动广告栏界面 1、创建水平滑动广告栏界面 在res/layout文…

Android:安卓开发采用Volley网络框架+MySQL数据库,实现从服务器获取数据并展示完成记单词APP

一、功能与要求 实现功能:设计一个记单词APP。服务器采用Tomcat,数据库采用Mysql。实现用户的注册登录功能以及单词的增删改查。 指标要求:实现UI布局;将系统数据保存到Mysql数据库中,并采用Volley网络框架实现从服务…

Java基础---集合框架四(Map)

2015-4-19 一、Map集合 1、Map接口概述 将键映射到值的对象 一个映射不能包含重复的键 每个键最多只能映射到一个值 2、Map接口和Collection接口的不同 Map是双列的,Collection是单列的 Map的键唯一,Collection的子体系Set是唯一的 Map集合的数据结构值针对键有效&#xff0…

如何在GraphQL和Vue中构建文件处理应用

介绍 (Introduction) In this tutorial, we’ll go over how to handle file uploads in GraphQL by building a full-stack app. This tutorial will be divided into two main sections: building the GraphQL API, and creating the frontend app. The GraphQL API will be …

[J2ME]RSSOwlMidlet(RSS无线阅读器)开源说明

郑昀ultrapower产品名称产品版本Keyword: RssReader RssFeed Channel j2me midp midlet kxml xmlpull RMS RssOwl java RSS无线阅读器0.7.1729[J2ME][开源]RSSOwlMidlet(RSS无线阅读器)开源说明摘要:本文档给出RSS无线阅读器J2ME版本的开源说明。第1章 简单描述RSS…

Android项目实战系列—基于博学谷(七)课程模块(中)

由于这个模块内容较多,分为上、中、下 三篇博客分别来讲述,请耐心阅读。 课程模块分为四个部分 课程列表 课程详情 视频播放 播放记录 课程模块(中)主要讲述课程详情部分 一、课程详情界面 1、创建课程详情界面 在com.boxuegu.activity包中…

如何在JavaScript中使用解构分配

JavaScript provides you with the ability to destructure objects and assign the individual units in one take. This allows you to get to the point of what you want to do and keep things clean. JavaScript使您能够分解对象并一次性完成分配各个单元的功能。 这使您…