Dart中使用implements及组合extends与implements时调用父类方法的问题咨询
您好,从您贴出的代码和描述来看,您在尝试用Dart的extends和implements时,对如何调用父类/接口类的方法存在疑惑,而且代码里还有几处需要修正的问题。咱们先梳理下您的代码(已补全截断部分并修正引号):
void main() { Dog d = Dog(); d.walking(); Cat c = Cat(); c.reproduction(); } // 父类 class Mammal { void reproduction() { print("Mammals can mate"); } void climb() { print("Mammals can also climb the mountain"); } } // 父类 class Animal { void walking() { print("Animal is walking"); } void eating() { print("Animal is eating"); } } // 子类 class Dog implements Animal, Mammal { void walking() { print("walking() - Dog is walking"); eating(); reproduction(); print("class Dog--Implemented class calling the super class method--\n"); super.climb(); // 这里会直接报错! } void eating() { print("Eating() - Dog is eating"); } void reproduction() { print("Reproduction() - Dogs like to mate in the wild"); } // 缺少climb()方法的重写,不符合implements的要求 } // 补全您未贴完的Cat类示例 class Cat extends Mammal { // 可直接复用父类Mammal的reproduction方法,也可选择重写 }
核心问题:implements与extends的本质差异
这两个关键字的作用完全不同,直接决定了子类能否调用“父类”的方法实现:
extends是类继承:
子类会完整继承父类的非私有方法和属性实现,你可以用super.xxx()直接调用父类的原始逻辑,而且Dart是单继承,一个类只能继承一个父类。比如你的Cat extends Mammal,调用c.reproduction()时,默认就会执行Mammal类里的实现,当然你也可以重写这个方法覆盖逻辑。implements是接口实现:
Dart里所有类都能当作接口使用,当你implements一个类时,只是承诺子类会实现该类所有公共方法/属性的签名,但不会继承原类的任何实现逻辑。因此你根本不能用super调用原类的方法——子类完全没有继承它的代码,必须自己重写所有接口要求的方法。就像你的Dog类,implements了Animal和Mammal,就必须重写walking()、eating()、reproduction()、climb()四个方法,super.climb()是完全错误的写法,编译器会直接报错。
正确的实现方案
如果您想在子类中复用某个类的方法实现,同时遵循另一个类的接口规范,可以结合extends和implements:
class Dog extends Animal implements Mammal { // 实现Mammal接口的reproduction方法 @override void reproduction() { print("Reproduction() - Dogs like to mate in the wild"); } // 实现Mammal接口的climb方法 @override void climb() { print("Dog can climb short trees!"); // 如果想复用Mammal的climb逻辑,可用组合方式(创建实例调用) Mammal().climb(); } @override void walking() { // 通过extends继承的Animal,可用super调用父类的walking方法 super.walking(); print("walking() - Dog is walking"); // 调用自己重写的eating,也可通过super.eating()调用父类逻辑 eating(); reproduction(); print("class Dog--Calling super class method via extends--\n"); } // 可选重写Animal的eating方法 @override void eating() { print("Eating() - Dog is eating bones"); } }
这样一来:
- 通过
extends Animal,Dog可以用super调用Animal类的walking()和eating()方法; - 通过
implements Mammal,Dog必须实现reproduction()和climb()方法,若需要复用Mammal的逻辑,可通过创建实例调用的组合方式实现,而非super。
补充:复用多个类的逻辑怎么办?
如果您想同时复用多个类的方法实现,Dart的单继承就不够用了,这时候可以用Mixin(混入):
mixin MammalMixin { void reproduction() { print("Mammals can mate"); } void climb() { print("Mammals can also climb the mountain"); } } class Animal { void walking() { print("Animal is walking"); } void eating() { print("Animal is eating"); } } class Dog extends Animal with MammalMixin { @override void walking() { super.walking(); // 调用Animal的walking print("walking() - Dog is walking"); eating(); reproduction(); // 调用MammalMixin的reproduction climb(); // 调用MammalMixin的climb } }
Mixin可以让您灵活复用多个类的方法实现,比单纯的implements更适合代码复用场景。
备注:内容来源于stack exchange,提问作者Rajiv Iyer

