[Flutter]dart中extends、 implements、with的用法与区别

概述

  • 继承(关键字 extends)
  • 混入 mixins (关键字 width)
  • 接口实现(关键字 implements)

这三种关系有可能同时存在,但是有先后顺序
优先级:
extends -> width -> implements

解析

继承:

dart中的继承规则:

  • 子类使用extends关键词来继承父类
  • 子类会继承父类里面可见的属性和方法 但是不会继承构造函数
  • 子类能复写父类的方法 getter和setter
  • 子类重写超类的方法,要用@override
  • 子类调用超类的方法,要用super
  • 子类可以继承父类的非私有变量
示例:
class Person {
  //公有变量
  String name;
  num age;
  //私有变量
  String _gender = '男';
  //类名构造函数
  Person(this.name, this.age);

  work() {
    print("${this.name}在学习...");
  }
}

class Student extends Person {
  Student(String name, num age) : super(name, age);

  run() {
    print('run');
    work();
  }
}

main() {
  Student student = new Student("张三", 16);
  student.run();
}

运行结果:

run
张三在学习...
覆写方法work:
class Person {
  //公有变量
  String name;
  num age;
  //私有变量
  String _gender = '男';
  //类名构造函数
  Person(this.name, this.age);

  work() {
    print("${this.name}在学习...");
  }
}

class Student extends Person {
  String school = "清华大学";

  Student(String name, num age) : super(name, age);

  run() {
    print('run');
    work();
  }

  @override
  work() {
    print("${this.name} 在 ${school} 学习");
  }
}

main() {
  Student student = new Student("张三", 16);
  student.run();
}

整体和java的继承很类似

混合mixins(with)

这里是要着重介绍的,因为我是一个Android程序员,第一次接触这个关键字

  • Mixin 是复用类代码的一种途径, 复用的类可以在不同层级,之间可以不存在继承关系。
  • 通过 with 后面跟一个或多个混入的名称,来 使用 Mixin
  • 通过创建一个继承自 Object 且没有构造函数的类,来 实现 一个 Mixin 。 如果 Mixin 不希望作为常规类被使用,使用关键字 mixin 替换 class 。 例如:
mixin Family {
  String address;
  String house;

  void setFamilyInfo(String address, String house) {
    this.address = address;
    this.house = house;
  }

  getAddress() {
    return address;
  }
}
  • 作为mixins的类只能继承自Object,不能继承其他类
  • 作为mixins的类不能有构造函数
  • 一个类可以mixins多个mixins类
  • mixins绝不是继承,也不是接口,而是一种全新的特性
    使用:
class Person {
  //公有变量
  String name;
  num age;
  //私有变量
  String _gender = '男';
  //类名构造函数
  Person(this.name, this.age);

  work() {
    print("${this.name}在学习...");
  }
}

class Student extends Person with Family {
  String school = "清华大学";

  Student(String name, num age) : super(name, age);

  run() {
    setFamilyInfo("北京", "明天第一城");
    print('run');
    work();
  }

  @override
  work() {
    String add = getAddress();
    print("${this.name}的家在${add} 在 ${school} 学习");
  }
}

main() {
  Student student = new Student("张三", 16);
  student.run();
}

打印结果:

run
张三的家在北京 在 清华大学 学习

其他注意的点:

mixins有优先级顺序,我们通过一些例子看一下:

class A {
  run() {
    print("run A");
  }
}

class B {
  run() {
    print("run B");
  }
}

class C {
  run() {
    print("run C");
  }
}

class Test extends C with A, B {
}

main() {
  Test test = new Test();
  test.run();
}

打印结果:

run B

如果把with B去掉 只留下with A,再运行一次:

class Test extends C with A {}

main() {
  Test test = new Test();
  test.run();
}

打印结果:

run A

如果 Test类中覆写了父类C的run方法:

class Test extends C with A {
  @override
  run() {
    print("run Test");
  }
}

main() {
  Test test = new Test();
  test.run();
}

结论:
如果继承类、混合类中有相同的方法或变量,混合类会覆盖继承类的方法或变量,后混合的会覆盖先混合的方法或变量。
这个过程叫做mixins的线性化,具体过程:

  • 如果当前使用类重写了该方法,就会调用当前类中的方法。
  • 如果当前使用类没有重写了该方法,则会调用距离with关键字最远类中的方法。

with on 的用法

mixins不能继承于除Object之外的其他类,如果我们确实有继承的需要怎么办呢? Dart引入了一个关键字on
具体使用方法:

class A {
  void printInfo() {
    print("print A");
  }
}

mixin B on A {}

官网对它的描述:

指定只有某些类型可以使用的 Mixin - 比如, Mixin 可以调用 Mixin 自身没有定义的方法 - 使用 on 来指定可以使用 Mixin 的父类类型

如果我们用on关键字限定了mixin ,那么这个mixin 只能适用于on后面限定的类的子类
举个例子:


image.png

这种情况C类是会报错的,报错信息:

'B' can't be mixed onto 'Object' because 'Object' doesn't implement 'A'.

需要将C类继承于A类, 如下:


image.png

报错消失

接口实现(implements)

Dart是没有interface的,但是Dart中的每个类都是一个隐式的接口,这个接口包含类里的所有成员变量,以及定义的方法。如果有一个类 A,你想让类B拥有A的API,但又不想拥有A里的实现,那么你就应该把A当做接口,类B implements 类A.

所以在Dart中:class 就是 interface

  • 当class被当做interface用时,class中的方法就是接口的方法,需要在子类里重新实现,在子类实现的时候要加@override
  • 当class被当做interface用时,class中的成员变量也需要在子类里重新实现。在成员变量前加@override
/*
Dart中一个类实现多个接口:
*/

abstract class A{
  String name;
  printA();
}

abstract class B{
  printB();
}

class C implements A,B{  
  @override
  String name;  
  @override
  printA() {
    print('printA');
  }
  @override
  printB() {
    // TODO: implement printB
    return null;
  }
}

void main(){
  C c=new C();
  c.printA();
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容