美文网首页
Dart入门04 -- 类,构造函数,setter,getter

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

作者: YanZi_33 | 来源:发表于2022-02-19 23:01 被阅读0次

    • 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方法名是可以任意取;

    相关文章

      网友评论

          本文标题:Dart入门04 -- 类,构造函数,setter,getter

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