Dart入门04 -- 类,构造函数,setter,getter方法

  • Dart 是一种面向对象的语言,具有类和基于 mixin 的继承,每个对象都是一个类的实例,所有类都来自Object类;
  • Dart 使用 class 关键字表示一个类,对象具有由函数和数据(分别为方法和实例变量)组成的成员,我们通过 new 关键字来创建一个实例对象;
  • Dart关于class类的定义,与Java完全类似;
void main(List<String> args) {
  Person person = new Person("yanzi", 33);
  person.run();
  person.eat();
}

class Person {
  //属性成员
  String name;
  int age;

  //构造方法
  Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  //实例方法
  void run() {
    print("run");
  }

  void eat() {
    print("eat");
  }
}
  • 构造函数:类的构造函数,是用来创建实例对象的函数;
默认构造函数
  • 当class没有自定义构造函数时,系统会默认生成无参的构造函数;
void main(List<String> args) {
  //无参构造函数
  Person person = new Person();
  person.run();
  person.eat();
}

class Person {
  //属性成员
  String name;
  int age;

  //实例方法
  void run() {
    print("run");
  }

  void eat() {
    print("eat");
  }
}
自定义构造函数
  • 如果class自定义了构造函数,那么默认构造函数为Person()就会被覆盖,不能使用了;
void main(List<String> args) {
  Person person = new Person("yanzi", 33);
  person.run();
  person.eat();
}

class Person {
  //属性成员
  String name;
  int age;

  //自定义构造函数
  Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  //实例方法
  void run() {
    print("run");
  }

  void eat() {
    print("eat");
  }
}
  • 上述自定义构造函数,可采用语法糖的简洁写法,如下所示:
void main(List<String> args) {
  Person person = new Person("yanzi", 33);
  person.run();
  person.eat();
}

class Person {
  //属性成员
  String name;
  int age;

  //自定义构造函数 -- 语法糖
  Person(this.name, this.age);

  //实例方法
  void run() {
    print("run");
  }

  void eat() {
    print("eat");
  }
}
命名构造函数
  • 为构造函数,定义一个指定的名称;
void main(List<String> args) {
  Person person = Person.withNameAndAge("yanzi", 32);
  person.run();
  person.eat();

  Person person1 = Person.fromMap({"name": "li", "age": 30});
  person1.run();
  person1.eat();
}

class Person {
  //属性成员
  String name;
  int age;

  //命名构造函数
  Person.withNameAndAge(this.name, this.age);

  Person.fromMap(Map<String, dynamic> map) {
    this.name = map["name"];
    this.age = map["age"];
  }

  //实例方法
  void run() {
    print("run");
  }

  void eat() {
    print("eat");
  }
}
  • withNameAndAgefromMap,都是Person类的命名构造函数,有自己独有的函数名称;
构造函数包含可选参数
  • 在构造函数中,支持可选参数,在调用构造函数时,对于可选参数,可传或者不传;
void main(List<String> args) {
  Person person1 = Person("yanzi");
  Person person2 = Person("sss", age: 22);

  Person person3 = Person.init("aaa");
  Person person4 = Person.init("cccc", age: 26);
}

class Person {
  String name;
  int age;

  //其中age为可选参数
  Person(String name, {int age}) {
    this.name = name;
    this.age = age;
  }

  //其中age为可选参数
  Person.init(this.name, {this.age});
}
初始化列表
  • 与C++的语法类似;
  • 初始化列表的使用只能在构造函数中
  • 在构造函数的小括号后面,使用冒号: 连接初始化的列表;
main(List<String> args) {
  var p = Person("SF");
  print(p.age);
}

class Person {
  //被final修饰的变量为常量 只能被赋值一次
  final String name;
  final int age;

  //初始化列表与C++语法类似
  //创建对象时,若传入age,那么就使用传入的age,如果没有传入age,那么使用默认值10,age为可选参数
  Person(this.name, {int age}) : this.age = age ?? 10 {
  //在执行此大括号的代码时,对象已经初始化完毕了
  //必须保证在执行此大括号的代码之前,final修饰的name与age必须已经初始化
  //所以下面代码报错
  //this.age = 10;
  }

  //存在局限性 
  //Person(this.name, {this.age = 10});
}
  • Person(this.name, {int age}) : this.age = age ?? 10:初始化列表,在执行大括号中的代码之前,完成对象的初始化;
  • 可以在构造的时候初始化一些参数值,对于一些final修饰的属性初始化以后固定值不会在变,使用初始化列表,就非常合适;
重定向构造函数
  • 在一个构造函数中,去调用另一个构造函数,注意⚠️是在冒号后面使用this进行调用
main(List<String> args) {
  var p = Person("SF");
  print(p.age); //22
}

class Person {
  String name;
  int age;

  //调用自定义构造函数Person._internal
  Person(String name) : this._internal(name, 22);

  Person._internal(this.name, this.age);
}
常量构造函数
  • 在某些情况下,传入相同值时,我们希望返回同一个对象,这个时候,可以使用常量构造方法;
  • 默认情况下,创建对象时,即使传入相同的参数,创建出来的也不是同一个对象,但是若在构造函数前加上const进行修饰,那么可以保证同一个参数,创建出来的对象是相同的,这样的构造函数称之为常量构造函数
main(List<String> args) {
  const p1 = Person("liyanyan");
  const p2 = Person("liyanyan");
  
  //p1与p2是同一个对象
  print(identical(p1, p2)); 
}

class Person {
  final String name;

  const Person(this.name);
}
  • 注意常量构造函数,只存在一个final属性;
  • 拥有常量构造函数的类中,所有的成员变量必须是final修饰的;
工厂构造函数
  • Dart提供了factory关键字,用于通过工厂去获取对象;
  • 普通的构造函数,会默认返回创建出来的对象,而工厂构造函数,需要手动返回一个对象
  • 案例代码:
main(List<String> args) {

  final p1 = Person.withName("liyanyan");
  final p2 = Person.withName("liyanyan");

  print(identical(p1, p2)); //true
}

class Person {
  //对象属性
  String name;
  String color;

  //类属性
  static final Map<String, Person> _nameCache = {};
  static final Map<String, Person> _colorCache = {};

  //工厂构造函数
  //1.根据key值从缓存中获取对象,存在直接返回,不存在
  factory Person.withName(String name) {
    if (_nameCache.containsKey(name)) {
      return _nameCache[name];
    } else {
      final p = Person(name, "default");
      _nameCache[name] = p;
      return p;
    }
  }

  factory Person.withColor(String color) {
    if (_colorCache.containsKey(color)) {
      return _colorCache[color];
    } else {
      final p = Person("default", color);
      _colorCache[color] = p;
      return p;
    }
  }

  Person(this.name, this.color);
}
  • final修饰变量,保证变量不被胡乱修改;
setter与getter方法
  • setter方法中,可使用关键字set
  • getter方法中,可使用关键字get
void main(List<String> args) {

  Person person4 = Person.init("cccc", age: 26);

  person4.setNamee("ssssss");
  print(person4.name);
  print(person4.getNamee());

  person4.name = "gggg";
  print(person4.name);
  print(person4.getNamee());
}

class Person {
  String name;
  int age;

  //其中age为可选参数
  Person.init(this.name, {this.age});

  //使用set,get关键字的setter,getter方法
  set setName(String name) {
    this.name = name;
  }

  String get getName {
    return this.name;
  }

  //不采用set,get关键字的setter,getter方法
  void setNamee(String name) {
    this.name = name;
  }

  String getNamee() {
    return this.name;
  }
}
  • setter与getter方法中使用了setget关键字,格式如代码所示;
  • setter与getter方法中可以使用箭头函数,更加简便;
  • Dart中属性的get/set方法名是可以任意取;
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容