Flutter - 继承(extends)/混合 mixins (with)/接口实现(implements)

类型 解决什么问题 使用场景 限制
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中后一个覆盖前一个

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

推荐阅读更多精彩内容