Dart笔记 - extends、with、implements

文内所使用的Dart版本为2.17.0

一、对比

extends

数量: 仅一个
对象: 任意类(class)
附注:

  • 可覆写(建议使用@override注解)被继承对象所有的非静态(static)的属性方法
  • 对于用abstract修饰的属性或方法,若继承者不为抽象类则必需覆写。
  • 对于用final修饰的属性则为覆写其get方法。

with

数量: 多个(至少一个)
对象: 没有构造方法的任意类(class)或任意混入(mixin)
附注: (这里为表述简洁,使用了子类的说法代指了混入关系)

  • 属性和方法的覆写规则同extends
  • 可以直接使用mixin关键字修饰with对象(一定程度上可以把mixin看作是特殊的abstract class),此时可使用on关键字限定一个class或mixin对象,只有该被限定对象的子类可通过with使用该mixin修饰的对象(当on限定对象为mixin且其子类同时使用该被修饰对象时,在其子类的with子句中被限定对象要排在该被修饰对象之前)。
  • 对于各被混入对象的同名属性或方法,排列靠后的覆盖排列靠前的

implements

数量: 多个(至少一个)
对象: 任意类(class)或任意混入(mixin)
附注:

  • 被实现对象的所有非静态(static)属性和方法均被视为是抽象的(abstract),无论是否使用了abstract修饰。
  • 在上一条的前提下,属性和方法的覆写规则同extends

附注

  • 三者可以同时使用,顺序依次为extends、with、implements
  • extends和with同时使用时,对于同名属性和方法的覆盖顺序为:类中的覆写 > with > extends,对于super的指代:with > extends。对于implements,因其特性所以不讨论覆盖顺序(因为它相当于没有值或方法体,可以认为始终处于覆盖顺序的最底层)。
  • withimplements可以同时使用同一个对象,其效果等价于只有修饰了abstract关键字的属性或方法是抽象的。

二、示例

extends

// 压缩排版,下同
void main() {
  final b = B();
  b.c(); // B-c
  b.f(); // B-f
}

abstract class A {
  var a = 0;
  final b = 1;
  void c() { print('A-c'); }

  abstract int d;
  abstract final int e;
  void f();
}

class B extends A {
  @override void c() { print('B-c'); }

  @override int d = 0;
  @override int get e => 1;
  @override void f() { print('B-f'); }
}

with

基本使用:

void main() {
  E().test(); // B
  F().test(); // C
}

class A { A(); }

/*abstract */class B { void test() { print('B'); } }

mixin C { void test() { print('C'); } }

// class D with A {} // 错误:被混入对象不能有构造方法

class E with B {}

class F with C {}

排列靠后的覆盖排列靠前的:

void main() {
  C1().test(); // B
  C2().test(); // A
}

/*abstract */class A { void test() { print('A'); } }

mixin B { void test() { print('B'); } }

class C1 with A, B {}

class C2 with B, A {}

使用on限定:

void main() {
  D1().test(); // B1
  D2().test(); // B2
}

class A1 { void test() { print('A1'); } }

mixin B1 on A1 { void test() { print('B1'); } }

// class C1 with B1 {} // 错误:C1不是A1的子类

class D1 extends A1 with B1 {}

// ******

mixin A2 { void test() { print('A2'); } }

mixin B2 on A2 { void test() { print('B2'); } }

// class C2 with B2 {} // 错误:C2不是A2的子类

class D2 with A2, B2 {} // 不能是 “with B2, A2”,理由同上

implements

/*abstract */class A {
  var a = 0;
  void b() { print('A-b'); }
}

class B implements A { // 均被视为abstract
  @override int a = 1;
  @override void b() { print('B-b'); }
}

其它示例

覆盖顺序:

void main() {
  D().test(); // B2
  E().test(); // E
  F().test(); // F
  G().test(); // G
}

/*abstract */class A { void test() { print('A'); } }

/*abstract */class B1 { void test() { print('B1'); } }

/*abstract */class B2 { void test() { print('B2'); } }

/*abstract */class C1 { void test() { print('C1'); } }

/*abstract */class C2 { void test() { print('C2'); } }

// with > extends
class D extends A with B1, B2/* implements C1, C2*/ {}

// 类中覆写 > extends
class E extends A/* implements C1, C2*/ { @override void test() { print('E'); } }

// 类中覆写 > with
class F with B1, B2/* implements C1, C2*/ { @override void test() { print('F'); } }

// 类中覆写 > with > extends,对于implements因其特性不讨论
class G extends A with B1, B2/* implements C1, C2*/ { @override void test() { print('G'); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值