[译]Flutter - Dart的Mixin

原文在这里。写的不错,推荐各位看原文。编程

这里补充一下Mixin的定义: 只要一个类是继承自Object的并且没有定义构造方法,那么这个类能够是一个Mixin了。固然,若是你想让mixin的定义更加的清晰,可使用mixin关键字开头来定义。具体请参考这里app

原文截图体会一下风格。编程语言

正文

在经典的面向对象编程语言里必定会有常规的类抽象类接口。固然,Dart也有它本身的接口,不过那是另外的文章要说的。有的时候阴影里潜伏者另外的野兽:Mixin!这是作什么的,如何使用?咱们来一块儿发现。ide

没有mixin的世界

假设你在构建一个模拟野生动物的app,那么你须要一个Mosquito(蚊子)类。做为一个有预见性的开发人员,你会抽象蚊子们有的共通的东西而后放在一个抽象类里。ui

abstract class Insect {
  void crawl() {
    print('crawling');
  }
}

abstract class AirborneInsect extends Insect {
  void flutter() {
    print('fluttering');
  }

  void buzz() {
    print('buzzing annoyingly')
  }
}

class Mosquito extends AirborneInsect {
  void doMosquitoThing() {
    crawl();
    flutter();
    buzz();
    print('sucking blood');
  }
}
复制代码

很棒!你已经作到了!添加新的昆虫就如同微风拂过同样,根本不会有代码的冗余出现。。。一直到你发现你须要一个Swallow类(就是一种能够吃掉整个蚊子的东西)。spa

一样的也有不少鸟类共有的东西,咱们能够建立一个Bird类。这个时候问题就出现了 -- 鸟也会振动翅膀!可是,你无法把flutter方法从AirboneInsect类里面提取出来组成一个新的类Flutteringcode

为何?Bird类能够继承Fluttering类,可是AirboneInsect不能够,它已经继承了Insect类了。Dart可不支持多继承(真很好)。cdn

这下,你须要给Bird类添加一个flutter方法了。代码冗余发生了!对象

abstract class Bird {
  void chirp() {
    print('chirp chirp');
  }

  // Duplicate method
  void flutter() {
    print('fluttering');
  }
}

class Swallow extends Bird {
  void doSwallowThing() {
    chirp();
    flutter();
    print('eating a mosquito');
  }
}
复制代码

使用mixin

Mixin的定义是“一种把类代码用在多个继承树的方法”。简单的说,mixin让你不用继承就能够引入代码块的方法。声明一个mixin很是的简单:blog

mixin Fluttering {
    void flutter() {
        pring('fluttering');
    }
}
复制代码

这个mixin能够用在常规的类上面也能够用在抽象类,只须要一个with关键字。在野生动物模拟app例子里,你也许要用在抽象类上了。

mixin Fluttering {
  void flutter() {
    print('fluttering');
  }
}

abstract class Insect {
  void crawl() {
    print('crawling');
  }
}

abstract class AirborneInsect extends Insect with Fluttering {
  void buzz() {
    print('buzzing annoyingly');
  }
}

class Mosquito extends AirborneInsect {
  void doMosquitoThing() {
    crawl();
    flutter();
    buzz();
    print('sucking blood');
  }
}

abstract class Bird with Fluttering {
  void chirp() {
    print('chirp chirp');
  }
}

class Swallow extends Bird {
  void doSwallowThing() {
    chirp();
    flutter();
    print('eating a mosquito');
  }
}

复制代码

也能够在一个类上面使用多个mixin。若是须要在Bird类上用一个chirping mixn的话,就和Fluttering mixin一块儿用就好。

abstract class Bird with Fluttering, Chirping 复制代码

限制Mixin的使用

有的时候你不想让mixin用在早已存在的类上面,你只是想让它用在某些特定的类或者其子类上。这一般你的代码对早已存在的代码有依赖。

在野生动物app这个例子里,你发现仅仅支持swallow已经不够了。还有其余种类的鸟好比麻雀或者Blue Jay等。与麻雀不一样,不少其余的鸟须要从地里面啄食,种子啊,虫子啊的。。。

Bird抽象类添加方法是不可能的,由于不是全部的鸟都须要啄食。因此,为了不代码冗余,你能够建立一个叫作Pecking的mixin。

mixin Pecking {
  void peck() {
    print('pecking');
  }
}
复制代码

这至少比代码荣誉好不少了。可是,也会有人把这个mixin用在Insect类上。这样使用mixin问题就大了。

当你开始研究一个鸟类的动做的时候,你会发现鸟儿在逐出食物以后就会发出愉悦的鸟鸣。从当前的mixin里面调用chirp方法是不可能的。要改也很是简单,只要告诉Dart,Pecking mixin只能用在Bird类上面。如今调用Bird类的方法就没有问题了。

//...
mixin Pecking on Bird {
    void peck() {
        print('pecking');
        chirp();
    }
}

class Sparrow extends Bird with Pecking {}

class BlueJay extends Bird with Pecking {}
复制代码

结论

Mixin对于继承体系中避免代码的冗余很是有用处。mixin也能够被约束在只能够用在某些特定的类上面,这让他们成为了开发的一大利器!

相关文章
相关标签/搜索