1、类和构造函数

  1. class TestClass {
  2. int a;
  3. int b;
  4. // 构造函数
  5. TestClass(this.a, this.b);
  6. // 可选构造函数
  7. TestClass(this.a, {this.b = 0});
  8. // 命名构造函数,命名构造函数不可以继承
  9. TestClass.creat(this.a, this.b);
  10. }

Java一样,指定一个类型相同的方法就是普通构造函数。

类里没有显示的构造函数,默认一个隐式的无参构造函数,会优先调用父类无参的构造函数。

2、初始化列表

  1. class TestClass {
  2. int a;
  3. int b;
  4. //初始化列表
  5. TestClass(this.a) : b = 2;
  6. TestClass(this.a) : b = 2 {
  7. }
  8. }

初始化列表的执行顺序在整个构造函数的最前面,作用:

  • 可以调用父类的构造函数
  • 在构造函数方法体之前,初始化一些成员变量
  • 可以初始化final修饰的成员变量,因为执行方法体时,final修饰的成员变量已经不能修改

    3、构造函数的调用顺序

    如果子类继承父类,那么子类的构造函数要调用父类的构造函数,这时候分两种情况:
    1、自动帮你调用父类的构造函数
    2、显式调用父类的构造函数

    3.1、默认调用父类的无参构造函数

    如果没有显式的调用父类的构造函数,并且父类有一个无参的构造函数,那么调用顺序如下:
    初始化列表 —> 父类的无参的构造函数 —> 子类的无参的构造函数
    如果父类没有无参的构造函数,就需要显式的调用父类的构造函数了

    3.2、显示调用父类构造函数

    显示调用父类构造函数,应该在初始化列表中完成 ```dart class Person { String? name;

    Person.fromJson(Map data) { print(‘in Person’); } }

class Man extends Person { Man.fromJson(Map data) : super.fromJson(data) { print(‘in Man’); } } //执行顺序 //in Person //in Man

  1. <a name="eGUck"></a>
  2. ## 4、构造函数重定向
  3. 一个类中构造函数调用另一个构造函数实现重定向效果
  4. ```dart
  5. class TestClass {
  6. int a;
  7. int b;
  8. //初始化列表
  9. TestClass(int a) : this.creat(a, 9);
  10. TestClass.creat(this.a, this.b);
  11. }

5、常量构造函数

使用const函数进行修饰

  1. class TestClass {
  2. final String name;
  3. const TestClass(this.name);
  4. }

6、工厂构造函数

普通构造函数会默认返回创造出来的对象,工厂构造函数需要自己手动返回一个对象。

  1. class TestClass {
  2. String name;
  3. String type;
  4. static final Map<String, TestClass> _nameCache = {};
  5. static final Map<String, TestClass> _typeCache = {};
  6. TestClass(this.name, this.type);
  7. factory TestClass.creatWithName(String name) {
  8. if (_nameCache.containsKey(name)) {
  9. return _nameCache[name]!;
  10. } else {
  11. final test = TestClass(name, "default");
  12. _nameCache[name] = test;
  13. return test;
  14. }
  15. }
  16. factory TestClass.creatWithType(String type) {
  17. if (_typeCache.containsKey(type)) {
  18. return _typeCache[type]!;
  19. } else {
  20. final test = TestClass("default", type);
  21. _typeCache[type] = test;
  22. return test;
  23. }
  24. }
  25. }

7、继承

dart中不支持多继承,只支持单继承。见 3.2 显示调用父类构造函数 的示例

8、抽象类

可以只放类没有实现,但是抽象类不可以实例化

  1. abstract class Test1 {
  2. int test();
  3. }
  4. //同java,实体类继承抽象类后,必须实现抽象类的抽象方法
  5. class Test2 extends Test1 {
  6. @override
  7. int test() {
  8. // TODO: implement test
  9. return 1;
  10. }
  11. }

9、隐式接口

java中的继承还有点区别,当一个类当作接口使用时,必须实现这个接口中的所有方法

  1. class Test1 {
  2. void test() {}
  3. }
  4. class Test2 implements Test1 {
  5. @override
  6. void test() {
  7. // TODO: implement test
  8. }
  9. }

10、混入(Mixin)

mixin是一种在多类层次结构中复用代码的一种方式,允许子类在继承父类时混入其他类,实现多继承的效果。

  1. mixin Walker {
  2. void walk(String name){
  3. print("$name is walking");
  4. }
  5. }
  6. // 游泳
  7. mixin Swimmer {
  8. void swim(String name){
  9. print("$name is swimming");
  10. }
  11. }
  12. // 飞行
  13. mixin Flyer {
  14. void fly(String name){
  15. print("$name is flying");
  16. }
  17. }
  18. // 唱歌
  19. mixin Singer {
  20. void sing(String name){
  21. print("$name is singing");
  22. }
  23. }
  24. class Cat with Walker {}
  25. class Duck with Walker, Swimmer, Flyer, Singer{}

使用with关键字进行混入,后面可以有一个或多个混入的类名,混入后就可以使用混入的方法了。

10.1、混入的限制条件

使用on关键字进行限制

  1. mixin Singer on Bird{
  2. void sing(String name){
  3. print("$name is singing");
  4. }
  5. }

限制后就只能由Bird类以及子类能够混入,其他类就无法混入,防止滥用。