【翻译】Dart: extends vs implements vs with(Mixin)

2,041 阅读2分钟

原文:medium.com/@manoelsrs/…

stackoverflow.com/questions/4…

使用extends

继承允许我们创建新类,用来重用、扩展或修改已存的的类行为。在Dart中,只能继承一个超类,但是继承是可传递的。

class Vehicle {
  Vehicle(this.color);

  final String color;
  final String definition = 'Vehicle';
}

class Car extends Vehicle {
  Car(String color) : super(color);
}

class Hatch extends Car {
  Hatch(String color) : super(color);
}

main() {
  final hatch = Hatch('red');
  print('Result: ${hatch is Vehicle}');
  // Output -> Result: true
}

当class Car extends Vehicle,类Vehicle中实现的所有属性、变量、方法,类Car都可以获取到。

main() {
	final car = Car('red');
    print('Result: Car is a ${car.definition}');
    // Output -> Result: Car is a Vehicle
}

另外也可以覆盖超类的方法:

class Car extends Vehicle {
	Car(String color) : super(color);
    
    @override
    String get definition => 'Car ${super.definition}';
}

所以,当想要创建一个更具体版本的类时可以使用extends.

使用implements

如果你想要创建你自己的Car类,不想继承Vehicle类的所有属性、变量和方法,而只想继承Vehicle类型。这样,Car类就要实现Vehicle接口。

class Car implements Vehicle {
	Car(this.carColor);
    
    final String carColor;
    
    @override
    String get color => carColor;
    
    @override
    String get definition => '$carColor car';
}

main() {
	final car = Car('red');
    print('Result: definition: ${car.definition}');
    // Output -> Result: definition: red car
    print('Result: is Vehicle type: ${car is Vehicle}');
    // Output -> is Vehicle type: true
}

Dart允许实现多个类或接口;

☝️例子

假设你想实现一个鸟和鸭子的类。两个都是动物,但是鸟可以飞,鸭子既可以飞又可以游泳。怎么实现?

首先,创建超类和行为:

class Animal {}

abstract class Flyer {
	void fly() => print('I can fly!');
}

abstract class Swimmer {
	void swim() => print('I can swim!');
}

现在,创建Bird和Duck,实现合适的行为:

class Bird extends Animal implements Flyer {
	@override
    void fly() => print('I can fly!');
}

class Duck extends Animal implements Swimmer, Flyer {
	@override
    void fly() => print('I can fly!');
    
    @override
    void swim() => print('I can swim!');
}

有没有发现,使用implements就要实现fly和swim方法,代码重复。这种方式没有办法继承行为的实现。有没有可以重用实现代码的方式。

使用with

Mixin是一种不同类型的结构,只能通过关键字with使用。mixin被用来包含公共的代码片段,也就是重用代码。

Mixins是一种在多个类层级中重用代码的方式。

class Animal {}

abstract class Flyer {
	void fly() => print('I can fly!');
}

abstract class Swimmer {
	void swim() => print('I can swim!');
}

class Bird extends Animal with Flyer {}

class Duck extends Animal with Swimmer, Flyer {}

可以把abstract class替换成mixin。

Mixins 是一种 抽象和重用一组操作和状态的方式,很像extends一个类的时候重用代码的方式,只是不是多重继承的,只有一个超类。上面例子中也可以在类中覆盖mixin的方法。

总结(译者注)

Mixins注重一个类怎么实现它应该实现的事,它继承和分享具体的实现。

Implements注重一个类是什么,它是一种抽象的签名和类必须实现的承诺。