Flutter之dart基础 [关键字 1]

360 阅读4分钟

Flutter之dart基础 [关键字 1]

本文章主要介绍abstractextendsimplementswithonmixin这几个关键字的作用以及应用。

1. abstract

abstract是抽象,类class的修饰词,通常用来声明一些功能函数,但是自己并不需要实现。

我们实现一个物品,该物品有一个code属性,表示该物品的独一无二的编码。

/// 有编码的物品
abstract class Thing {
  int get code;
  Thing();
}

2. extends

extends是继承,可以继承抽象类,也可以继承普通父类,父类中的抽象方法需要子类来实现,普通方法则不用。

我们定义抽象动物的类,该动物有名字,可以打印日志。

/// 有编码的物品
abstract class Thing {
  int get code;
  Thing();
  String toString();
}

/// 动物
abstract class Animal with EatAnimal, Log implements Thing {
  final String name;
  Animal({this.name}) : super();
}

当子类和父类都是抽象类的情况下,子类不需要实现父类的方法。

如果子类是普通类,则需要实现父类的抽象方法,爷爷辈的抽象类则不需要实现,但是在使用没有实现的方法是没有效果的,也没崩溃。

/// 有编码的物品
abstract class Thing {
  int get code;
  Thing();
  String toString();
}

/// 动物
abstract class Animal extends Thing {
  final String name;
  Animal({this.name}) : super();
  String animalToString();
}

class Cat extends Animal {
  @override
  int get code => 0;

  @override
  String animalToString() {
    return 'cat string';
  }
}


  print(Cat().toString());
  print(Cat().animalToString());
  
  -------------log--------------
flutter: Instance of 'Cat'
flutter: cat string

3. implements

implements隐式接口,例如A implements B,那么A必须实现B中的所有方法(包含普通方法和抽象方法)。通常用于只是想使用B中定义的方法而不像使用B的实现。 而且implements需要实现的方法在抽象类中具有向下传递的效果。在抽象类中使用implements相当于导入方法。

可以导入mixinabstraceclass多种多个类。

 class Cat extends Animal implements EatAnimal, Normal, CatFatcher {
  @override
  int get code => 0;

  @override
  String animalToString() {
    return 'cat string';
  }

  @override
  void eat() {}

  @override
  void toNormal() {}

  @override
  void logMe() {}
}

abstract class CatFatcher {
  void logMe();
}

mixin EatAnimal {
  void eat() {
    print('动物在吃东西');
  }
}

class Normal {
  void toNormal() {}
}

4. mixin && with && on

mixin 装饰的方法用于挂载到其他类上,不具有向下传递效果。比如你买了一个手表,然后生了儿子,儿子出生会有手表吗?答案是不会的,儿子需要手表的话需要再次带(with一次)到手上即可。。

例子

mixin EatAnimal {
  void eat() {
    print('动物在吃东西');
  }
}
mixin WalkAnimal {
  void run() {
    print('动物在跑');
  }
}

/// 动物
abstract class Animal with EatAnimal, Log implements Thing {
  final String name;
  Animal({this.name}) : super();
}

Animal:实现了可以吃,打印日志功能,implements Thing之后需要实现Thing所有方法,而在Animal中并无log实现,为什么没报错,因为with Log已经导入了该方法,所以无需再次实现。

那么如果with Log然后子类又实现了该方法会怎么样?

class Person extends Animal {
  final String name;
  Person({this.name})
      : super(
          name: name,
        );
  @override
  int get code => this.name.hashCode;

  @override
  void log() {
    print('Person log ');
  }
}

Person(name: '老李')..log()

输出:

flutter: Person log

如果with Log在子类中实现了,则会覆盖该方法。

如果 多个mixin实现了同样一个方法,最后被一个类同时混入了会怎么样?

mixin Log2 {
  void log() {
    print('log2 is log');
  }
}

class Person extends Animal with Log2 {
  final String name;

  Person({this.name})
      : super(
          name: name,
        );

  @override
  int get code => this.name.hashCode;
}


Person(name: '老李')..log()

输出:

flutter: log2 is log

多个mixin实现了同样的方法,子类又没有实现,则按照with的最后一个执行。

mixin添加一个限定条件,给指定类可以添加的方法。


mixin Log2 on Animal {
  void log() {
    print('log2 is log');
  }
}


class Person extends Animal with Log2 {
  final String name;

  Person({this.name})
      : super(
          name: name,
        );

  @override
  int get code => this.name.hashCode;
}

mixin on了另外一个mixin,则使用的时候需要依赖放在被依赖的前边。

WalkAnimal放在Log2前边。

mixin WalkAnimal {
  void run() {
    print('动物在跑');
  }
}

mixin Log2 on WalkAnimal {
  void log() {
    print('log2 is log');
  }
}


class Person extends Animal with WalkAnimal, Log2{}

总结

  1. 抽象类可以继承抽象类,并且implements其他类和with 其他的类,当with的类有相同的方法,则按照顺序覆盖,最后一个生效,如果子类实现了该类,则执行子类的方法。
  2. implements只是导入所有方法(抽象和普通方法)。
  3. A with B,C implements D,查找方法的优先级A>C>B
  4. A with B implements Dabstract B extends E implements F,则在A中需要实现F的所有方法和B E的抽象方法。