美文网首页flutter相关
Flutter - 继承(extends)/混合 mixins

Flutter - 继承(extends)/混合 mixins

作者: nero_i | 来源:发表于2022-06-22 19:25 被阅读0次
类型 解决什么问题 使用场景 限制
extends 子类继承 子类继承父类 可以有构造方法和实例变量
Mixin(with) 实现类似多继承,能力集 不通过继承,获取一个类的能力 不能有构造方法,可以有实例变量
Extension(on) 给系统类【例如String类添加功能】 在无法修改被扩展类源码的情况下 不能有构造方法和实例变量
Implement 声明和实现的解耦 模版方法的实现【设计模式的一种】 暂无

继承(extends)

使用extends关键词来继承父类

  • 子类会继承父类里面可见的属性和方法 但是不会继承构造函数
  • 子类能复写父类的方法 getter和setter
  • 子类重写超类的方法,要用@override
  • 子类调用超类的方法,要用super
  • 子类可以继承父类的非私有变量 (类中私有变量和函数的定义:名称前面带_)
class Person {
  String? name;
  int? age;

  /// 构造函数
  Person(this.name);

  /// 私有属性,对于子类不可见
  String? _birthDay;

  /// 计算属性
  bool get isAdult => (age ?? 0) >= 18;

  void run() {
    print('Person runing');
  }
}

class Student extends Person {
  /// 子类构造函数
  Student(String? name) : super(name);

  /// 重写父类属性
  @override
  bool get isAdult => (age ?? 0) > 20;

  @override
  void run() {
    // super.run();
    print('Student runing');
  }

  /// 子类自有方法
  void study() {
    print("Student can studying");
  }
}

void main() {
  Student student = Student("li sha");

  /// 调用自己方法
  student.study(); // Student can studying
  /// 访问父类属性
  student.age = 18;

  /// 调用父类方法
  student.run(); // Person runing

  print(student.isAdult); // false

  /// 继承中 多态的使用
  Person person = Student('jekson ');
  person.run(); //Student runing

  // Tips: Error 这里无法访问到子类方法,因为使用多态生成的对象是Person,Person中没有study方法
  // person.study(); //Student runing

  /// 使用is 意思是:将person 转化成 Student对像,就可以访问子类方法了
  if (person is Student) {
    person.study();
  }
}

tips: 注意继承中 多态的使用

混合 mixins (with)

mixins的中文意思是混入(两个类混合在一起),就是在类中混入其他功能。简单的理解,就是在现有类的基础上,引入一些新的变量和方法。

  • 作为mixins的类只能继承自Object,不能继承其他类
  • 作为mixins的类不能有构造函数
  • 一个类可以mixins多个mixins类
  • mixins不是继承,也不是接口,而是一种全新的特性。
最简单的mixin

mixin本身可以是抽象的,可以定义各种方法属性,也可以是抽象的,等后续类去实现

void main(List<String> args) {
  XuModel model = XuModel();
  model.xuTest2();
  model.xutest1();
  print('xuValue: ${model.xuValue}');
}

/// mixin本身可以是抽象的,可以定义各种方法属性,也可以是抽象的,等后续类去实现
mixin TestXuMixin {
  // 定义属性
  var xuValue = 3;
  // 抽象方法
  void xutest1();

  void xuTest2() {
    print('xuTest2');
  }
}


class XuModel with TestXuMixin {
  @override
  void xutest1() {
    // 该函数mixin 定义未实现,混入对象,必须要实现
    print("xutest1 - xuValue : $xuValue");
  }
}
基于某个类型的mixin

当使用on关键字(限定类型),则表示该mixin只能在那个类的子类使用了,那么结果显然的,mixin中可以调用那个类定义的方法、属性

class BaseObject {
  void method() {
    print('call method');
  }
}

mixin TestMixin on BaseObject {
  void test() {
    print('test');
  }

  int testInt = 1;
  void test2() {
    method();
  }

  void test3(); // 抽象方法
}

class Test extends BaseObject with TestMixin {
  @override
  void test3() {
    // TODO: implement test3
  }
}

void main() {
  Test().test(); // test
  print(Test().testInt); // 1
  Test().test2(); // call method
}
多个mixin

如果mixin存在冲突的部分,后面会覆盖前面的,没有冲突的则会保留,所以可以存在后面的mixin修改了前面的mixin的一部分逻辑的情况,不需要直接继承即可实现覆盖,避免了更复杂的继承关系

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

  int testInt = 1;

  void test2();
}

mixin TestMixin2 {
  int testInt = 2;

  void test3() {
    print('test3');
  }
}

class Test with TestMixin, TestMixin2 {
  @override
  test2() {
    print('test2');
  }
}

void main() {
  Test().test(); // test
  print(Test().testInt); // 2 后面会覆盖前面的mixin
  Test().test2(); // test2
  Test().test3(); // test3
}

mixin实现多重继承
mixin TestMixin on BaseClass {
  void init() {
    print('TestMixin init start');
    super.init();
    print('TestMixin init end');
  }
}

mixin TestMixin2 on BaseClass {
  void init() {
    print('TestMixin2 init start');
    super.init();
    print('TestMixin2 init end');
  }
}

class BaseClass {
  void init() {
    print('Base init');
  }

  BaseClass() {
    init();
  }
}

class TestClass extends BaseClass with TestMixin, TestMixin2 {
  @override
  void init() {
    print('TestClass init start');
    super.init();
    print('TestClass init end');
  }
}

void main() {
  TestClass();

  /// TestClass init start
  /// TestMixin2 init start
  /// TestMixin init start
  /// Base init
  /// TestMixin init end
  /// TestMixin2 init end
  /// TestClass init end
}

接口实现(implements)

接口的实现,基于定义的一个抽象类,抽象类中仅定义方法,没有具体的实现,子类通过implements的方法,在子类中实现具体的方法。

  • implements与extends最⼤的不同就是允许后⾯接上多个普通或者抽象类,当我们使⽤B implement A修饰时,那么A中的所有的属性和⽅法都要在B中实现,⽆论它原来是抽象⽅法还是普通⽅法。
abstract class Run {
  var runValue;
  void runing() {
    print('runding');
  }
}

abstract class Eat {
  void eat();
}

class Person implements Run, Eat {
  @override
  void runing() {
    print("Person runing");
  }

  @override
  void eat() {
    print("Person eating");
  }

  @override
  var runValue = 100;
}

class Lion extends Run with Eat {
  /// 抽象类中实现的方法
  /// 继承抽象类可以不用实现(子类继承父类方法,可以选择是否重写)
  @override
  void runing() {
    /// 继承抽象类可以调用super
    super.runing();
    print("Lion runing");
  }

  @override
  void eat() {
    print("Lion eating");
  }
}

void main(List<String> args) {
  Person().runing();
  Person().eat();

  Lion().eat();
  Lion().runing();
}

tips:

mixin:定义了组块。

mixin on:限定了使⽤组块的宿主必须要继承于某个特定的类;在mixin中可以访问到该特定类的成员和⽅法。

with负责组合组块,而with后⾯跟的类并不⼀定需要是mixin的,abstract class 和普通类都可以。

extends with 修饰会覆盖同名方法,with中后一个覆盖前一个

相关文章

网友评论

    本文标题:Flutter - 继承(extends)/混合 mixins

    本文链接:https://www.haomeiwen.com/subject/rmmuvrtx.html