likes
comments
collection
share

Dart中的implements、extends、mixin

作者站长头像
站长
· 阅读数 8

一、关键词

  • 组成单元:普通类、抽象类(abstract)
  • 连接关系:实现(implements)、继承(extend)、混入(mixin)

相比于Java,dart没有interface接口,添加了mixin混入

二、组成单元

2.1 普通类

可以新建实例,可以被extends、implements、mixin。

2.2 抽象类 - abstract

抽象abstract通常用于描述父类拥有一种行为但无法给出细节实现,而需要通过子类来实现抽象的细节。这种情况下父类被定义为抽象类,子类继承父类后实现其中的抽象方法。

  • 抽象类用abstract来实现,不过抽象函数无需使用abstract,直接给出定义不给出方法体实现即可。
  • 抽象类中可以有数据,可以有常规函数,可以有抽象函数,但抽象类不能实例化。子类继承抽象类后必须实现其中的抽象函数
void main() {
  // Abstract classes can't be created with a 'new' expresson
  // 抽象类不能新建实例类
//   var p = new Person(); 
  
  var t = new Teacher();
  t.printName();
  
  var s = new Student();
  s.printName();
}

abstract class Person {
  static const String name = "akironer";
  void printName() {
    print(name);
  }
}

// 抽象类 继承方法使用
class Teacher extends Person {
  
}

// 抽象类 接口方法使用
class Student implements Person {
  void printName() {
    print('akironer2');
  }
}

三、关系连接

3.1 继承 - extend

Dart语言标榜自己为“单继承”,也就是一个类只能有一个直接的父类。如果一个类没有显式地声明父类,那么它会默认继承Object类。此外Dart语言又提供了混入(Mixin)的语法,允许子类在继承父类时混入其他类。

  • 子类可以继承父类里面 可见的属性和方法。对于Java来说,可见指的是非private修饰;对Dart来说,指的是非下划线_开头。
  • 子类调用父类的方法,使用super关键字。子类重写父类的方法,使用override关键字
  • 子类不会继承父类的构造函数。

3.2 实现 - implements

Dart语言中没有接口(interface)的关键字,但是有实现(implements)关键字,Dart中可以将类(是否为抽象无关)当做隐式接口直接使用,当需要使用接口时,可以声明类来代替。

void main() {
  var dog = new Dog();
  dog.eat();
  dog.swim();
  dog.walk();
}

abstract class Animal{
  static const String name = 'AA';
  void display(){
    print("名字是:${name}");
  }
  void eat(); //抽象方法
}

// 抽象类作为接口
abstract class swimable{ 
  void swim();
}

// 普通类作为接口
class walkable{ 
  void walk(){}
}

class Dog extends Animal implements swimable, walkable {
  @override
  void eat() {
    print("eat");
  }
  @override
  void swim() {
    print("swim");
  }
  @override
  void walk() {
    print("walk");
  }
}

3.2 混入 - mixin

mixin一般用于描述一种具有某种功能的组块,而某一对象可以拥有多个不同功能的组块。 mixin用于修饰类,和abstract类似,该类可以拥有成员变量、普通方法、抽象方法,但是不可以实例化。

  • mixins不是一种在经典意义上获得多重继承的方法。
  • mixins是一种抽象和重用一系列操作和状态的方法。
  • 它类似于扩展类所获得的重用,但它与单继承兼容,因为它是线性的。

3.2.1 简单应用

最简单的mixin由mixin & with关键字组成。

‘教师‘ 一种能力是 '绘画'

void main() {
  Teacher().draw();
}

mixin DrawFunc {
  String content = '..';
  String what();
    
  void draw() {
    print('I can draw ${what()}');  
  }
}

class Teacher with DrawFunc {
  String what() => "car";
}

3.2.2 限定类型(mixin...on)

当我们在mixin上使用了on关键字,那么mixin只能在那个类的子类上使用,而mixin可以调用那个类的方法。

限定 '绘画' 这种能力只能够用在 '人类' 上面

void main() {
  Teacher().draw();
}

class Person {}

mixin DrawFunc on Person {
  String content = '..';
  String what();
    
  void draw() {
    print('I can draw ${what()}');  
  }
}

class Teacher extends Person with DrawFunc {
  String what() => "car";
}

3.2.3 多个类型

在 '绘画' 的基础上,我们增加一种新的能力 '唱歌'

void main() {
  Teacher().draw();
  Teacher().sing();
}

class Person {}

mixin DrawFunc on Person {
  String content = '..';
  String what();

  void draw() {
    print('I can draw ${what()}');  
  }
}

mixin SingFunc on Person {
  void sing() {
    print('I can sing');
  }
}

class Teacher extends Person with DrawFunc, SingFunc {
  String what() => "car";
}

3.2.4 组合组块

  • mixin:定义了组块。
  • on:限定了使用mixin组块的宿主必须要继承于某个特定的类;在mixin中可以访问到该特定类的成员和方法。
  • with:负责组合组块,而with后面,这一点需要注意,例如下面这样:
void main() {
  Teacher().draw();
  Teacher().sing();
  Teacher().dance();
}

class Person {}

mixin DrawFunc on Person {
  
  String content = '..';
  
  String what();
    
  void draw() {
    print('I can draw ${what()}');  
  }
}

mixin SingFunc on Person {
  void sing() {
    print('I can sing');
  }
}

abstract class DanceFunc {
  void dance() {
    print('I can dance');
  }
}

class Teacher extends Person with DrawFunc, SingFunc, DanceFunc {
  String what() => "car";
}

四、总结。

  • mixin可以理解为一个个的功能组块:哪些宿主需要哪些功能就with到上去。
  • on关键字一方面是为了限制组块的应用场景,也可以为多个组块提供公共的基础功能。

参考资料

Flutter Tips - implements、extends、mixin

转载自:https://juejin.cn/post/6973906667142381605
评论
请登录