Dart语法基础系列七《类》

2021-11-10 15:02:47 浏览数 (1)

类在每个语言都是最核心的内容。dart 的类与其他语言差别不是很大,但是也有出入。

类属性


类里直接写属性是报错的,必须有默认值初始化或者构造函数赋值。

可以给一个默认值或者可选

代码语言:javascript复制
class Person {
  String name = "小明";
  int age = 3;
  String? sex;
}

构造函数


类默认会生成构造函数。构造函数分为:

  • 常规类名构造
  • 命名构造函数

常规构造函数

常规写法

代码语言:javascript复制
Person(String name, int age, String sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
  }
}

简写

代码语言:javascript复制
class Person {
  String name = "小明";
  int age = 3;
  String? sex;

  Person(this.name, this.age, this.sex);
}

命名构造函数

ClassName.identifier的方式创建,可以命名多种构造函数。

常规写法
代码语言:javascript复制
Person.formJson(Map json) {
    this.name = json['name'];
    this.age = json['age'];
    this.sex = json['sex'];
}
利用:语法,实现简写
代码语言:javascript复制
Person.formJson(Map json)
      : name = json['name'],
        age = json['age'],
        sex = json['sex'];

工厂构造函数

dart利用工厂设计模式实现单例构造。

根据名称缓存,一个人名只能对应一个实例吗。比如去找小明,多次声明只能找那一个人。

代码语言:javascript复制
class Person {
  String name = "小明";
  int age = 3;
  String? sex;

  // Person(this.name, this.age, this.sex);

  // Person.formJson(Map json) {
  //   this.name = json['name'];
  //   this.age = json['age'];
  //   this.sex = json['sex'];
  // }

  // Person.formJson(Map json)
  //     : name = json['name'],
  //       age = json['age'],
  //       sex = json['sex'];

  static final Map<String, Person> _cache = <String, Person>{};

  factory Person(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name]!;
    } else {
      final person = Person._initName(name);
      person.age = 21;
      _cache[name] = person;
      return person;
    }
  }

  Person._initName(this.name);
}

void main(List<String> args) {
  // var p1 = Person.formJson({'name': '小红', 'age': 18, 'sex': '男'});
  // print(p1.name);

  var xiaoming = Person('xiaoming');
  print(xiaoming.age);

  var xiaoming1 = Person('xiaoming');
  xiaoming1.age = 23;
  print(xiaoming.age);
}

调用发现最后都是一个实例。

常量构造函数

如果该类生成的对象是固定不变的, 那么就可以把这些对象定义为编译时常量。 为此,需要定义一个 const 构造函数, 并且声明所有实例变量为 final。

代码语言:javascript复制
class Person {
  final String name;
  final int age;
  final String? sex;
  const Person(this.name, this.age, this.sex);
}

void main(List<String> args) {
  var p1 = const Person("xiaoming", 16, "男");
  var p2 = const Person("xiaoming", 16, "男");
  print(identical(p1, p2));
}

方法


方法是为对象提供行为的函数。

实例方法

普通类的方法

代码语言:javascript复制
run() {
    print("跑");
 }

类方法(静态方法)

静态方法不能使用实例变量

代码语言:javascript复制
 static isAdult(age) {
    return age > 18 ? true : false;
  }

Getter 和 Setter

Getter 和 Setter 是用于对象属性读和写的特殊方法。 回想之前的例子,每个实例变量都有一个隐式 Getter ,通常情况下还会有一个 Setter 。 使用 get 和 set 关键字实现 Getter 和 Setter ,能够为实例创建额外的属性。

代码语言:javascript复制
class Rectangle {
  num left, top, width, height;

  Rectangle(this.left, this.top, this.width, this.height);

  // 定义两个计算属性: right 和 bottom。
  num get right => left   width;
  set right(num value) => left = value - width;
  num get bottom => top   height;
  set bottom(num value) => top = value - height;
}

void main() {
  var rect = Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);
  rect.right = 12;
  assert(rect.left == -8);
}

继承


dart类肯定也是可以继承的,和其他语言一样。

下面一个例子可以讲明白继承的一些应用:

  • 方法的重写
  • super 调用父类
  • 多态(父类指针指向子类,但是还是子类实例)
代码语言:javascript复制
class Person {
  final String name;

  run() {
    print('run');
  }

  Person(this.name);
}

class Student extends Person {
  Student(String name) : super(name);

  @override
  run() {
    print("studnet run");
  }
}

void main(List<String> args) {
  Person s1 = Student('小明');
  s1.run(); //studnet run
}

0 人点赞