• Dart 类与对象


    类是通过 class 关键字声明的代码段,包含属性和方法

      属性:用来描述类的变量
      方法:类中的函数称为类的方法

    对象是类的实例化结果(var obj = new MyClass())

    编程方式
      面向对象编程(OOP)
      面向过程编程(POP)
    // 声明类
    class Person {
      // 类的属性
      String name = 'Roger';
      // 类的方法
      void getInfo() {
        print(this); // Instance of 'Person'
        print('My name is $name'); // My name is Roger
        print('我的名字叫 ${this.name}'); // 我的名字叫 Roger
      }
    }
    
    void main() {
      // 实例化类,然后得到一个对象
      Person p = new Person();
      // 访问类中的属性
      print(p.name); // Roger
      // 访问类的方法
      p.getInfo();
    }
    构造器(构造函数)

    默认构造函数
      与类同名的函数,在实例化时,自动被调用
    class Point {
      num x, y;
      // 默认构造函数
      Point() {
        print('这是默认的构造函数,实例化时,会第一个被调用。');
      }
    }
    
    void main() {
      Point p = new Point();
      print(p.x);
      // 这是默认的构造函数,实例化时,会第一个被调用。
      // null
    }
    class Point {
      num x, y;
      // 默认构造函数
      // Point() {
      //   // this可以省略
      //   x = 0;
      //   y = 0;
      // }
    
      Point(num x, num y) {
        // 当命名指向有歧义时,this 不能省略
        // x = x;
        // y = y;
        this.x = x;
        this.y = y;
      }
    }
    
    void main() {
      Point p = new Point(3, 4);
      print(p.x); // 构造器中参数与类属性同名,省略this时,输出结果为 null;加上this,输出结果为 3
    }
    class Point {
      num x, y;
      // 默认构造函数的简写
      Point(this.x, this.y);
    }
    
    void main() {
      Point p = new Point(2, 4);
      print(p.x); // 2
    }
    命名构造函数
      在类中使用命名构造函数(类名.函数名)实现多个构造器,可以提供额外的清晰度
    class Person {
      String name;
      int age;
    
      // 默认构造函数
      Person(this.name, this.age);
    
      // 命名构造函数 -- 提供 Person 类的示例
      Person.example() {
        name = '张三';
        age = 23;
      }
    
      // 命名构造函数 -- 使用命名参数传值
      Person.namedParameter({name, age}) {
        this.name = name;
        this.age = age;
      }
    
      void getInfo() {
        print('姓名:$name, 年龄:$age');
      }
    }
    
    void main() {
      Person p1 = new Person('李四', 24);
      Person p2 = new Person.example();
      Person p3 = new Person.namedParameter(name: '光头强', age: 45);
    
      p1.getInfo(); // 姓名:李四, 年龄:24
      p2.getInfo(); // 姓名:张三, 年龄:23
      p3.getInfo(); // 姓名:光头强, 年龄:45
    }

    常量构造函数
      如果类生成的对象不会改变,可以通过常量构造函数使这些对象成为编译时常量
    class ConstantClass {
      // 属性必须通过 final 声明
      final String book;
      // const String author; // Only static fields can be declared as const
      final String author;
    
      // 常量构造函数,必须通过 const 声明
      const ConstantClass(this.book, this.author);
    }
    
    void main() {
      // 声明不可变对象,必须通过 const 关键字
      var c1 = const ConstantClass('西游记', '吴承恩');
      var c2 = const ConstantClass('西游记', '吴承恩');
      print(c1 == c2); // true
    
      // 常量构造函数,可以当作普通构造函数使用
      var c3 = new ConstantClass('西游记', '吴承恩');
      var c4 = new ConstantClass('西游记', '吴承恩');
      print(c3 == c4); // false
    
      // 实例化时,new关键字可以省略
      var c5 = new ConstantClass('西游记', '吴承恩');
      var c6 = new ConstantClass('西游记', '吴承恩');
      print(c5 == c6); // false
    }
    工厂构造函数
      通过 factory 声明,工厂函数不会自动生成实例,而是通过代码来决定返回的实例
    class Car {
      int wheels;
    
      static Car instance;
    
      // 命名构造函数
      Car.newCar(this.wheels);
    
      // 工厂构造函数 -- 接受一个可选参数并赋默认值4
      factory Car([int wheels = 4]) {
        // 工厂构造函数中,不能使用 this 关键字
        // print(this.wheels); // Invalid reference to 'this' expression
    
        // 第一次实例化
        if (Car.instance == null) {
          Car.instance = new Car.newCar(wheels);
        }
        // 非第一次实例化
        return Car.instance;
      }
    }
    
    void main() {
      // Car c1 = new Car();
      // Car c2 = new Car(6);
      // print(c1.wheels); // 4
      // print(c2.wheels); // 4
    
      Car c1 = new Car(6);
      Car c2 = new Car();
      print(c1.wheels); // 6
      print(c2.wheels); // 6
      print(c1 == c2); // true
    }
    访问修饰

    Dart 没有访问修饰符(public, protected, private),在 Dart 类中,默认的访问修饰符是公开的(即 public)

    如果要使用私有属性(private),需要同时满足以下两个条件:
    (1)、属性或方法以_(下划线)开头
    (2)、只有把类单独抽离出去,私有属性和方法才起作用
    class Person {
      String name;
    
      // 声明私有属性
      num _age = 8;
    
      Person(this.name);
    
      num getAge() {
        return this._age;
      }
    }
    import 'lib/Person.dart';
    
    void main() {
      Person p = new Person('Rogers');
      print(p.name); // Rogers
    
      // 访问私有属性
      // print(p._age); // The getter '_age' isn't defined for the type 'Person'.
    
      print(p.getAge()); // 8
    }
    Getter与Setter

    Getter(获取器)是通过 get 关键字修饰的方法
      函数没有小括号,访问时也没有小括号(像访问属性一样访问方法)

    Setter(修改器)是通过 set 关键字修饰的方法
      访问时,像设置属性一样给函数传参
    class Circle {
      final double PI = 3.1415926;
      num r;
    
      Circle(this.r);
    
      // 使用 get 声明的方法,不能有小括号
      // num get area() { // Getters must be declared without a parameter list.
      num get area {
        return this.PI * this.r * this.r;
      }
    
      set setR(r) {
        this.r = r;
      }
    }
    
    void main() {
      Circle c = new Circle(3);
    
      // 通过 Setter 修改属性
      c.setR = 10;
    
      print(c.area); // 314.15926
    }
    初始化列表

    作用:在构造函数中设置属性的默认值

    时机:在构造函数体执行之前执行

    语法:使用逗号分隔初始化表达式

    场景:常用于设置 final 常量的值
    class Rect {
      double height;
      double width;
    
      // 方案一:使用可选参数赋默认值
      // Rect([double height = 3.0, double width = 2.0]) {
      //   this.height = height;
      //   this.width = width;
      //   print('height: $height,  $width');
      // }
    
      // 初始化列表
      Rect()
          : height = 3.0,
            width = 2.0 {
        print('height: $height,  $width');
      }
    }
    
    void main() {
      Rect r = new Rect(); // height: 3.0,  2.0
    }
    class Point {
      double x, y, z;
    
      Point(this.x, this.y, this.z);
    
      // 初始化列表的特殊用法(重定向构造函数)
      Point.twoD(double x, double y) : this(x, y, 0);
    }
    
    void main() {
      // 实例化坐标
      Point p1 = new Point(1, 2, 3);
      print(p1.z); // 3.0
    
      Point p2 = new Point(1, 2, 0);
      print(p2.z); // 0.0
    }
    static

    static 关键字用来指定静态成员
      通过 static 修饰的属性是静态属性
      通过 static 修饰的方法是静态方法

    静态成员可以通过类名称直接访问(不需要实例化)
      实例化是比较消耗资源的,声明静态成员,可以提高程序性能

    静态方法不能访问非静态成员,非静态方法可以访问静态成员
      静态方法中不能使用 this 关键字
      不能使用 this 关键字访问静态属性
    class Person {
      static String name = 'Rogers';
      int age = 16;
    
      void printInfo() {
        // 不能通过this关键字访问静态属性
        // print(this.name);
    
        // 非静态方法,可以访问静态属性
        print(name);
        print(age);
    
        // 非静态方法,可以访问静态方法
        printName();
      }
    
      static void printName() {
        // 不能通过this关键字访问静态属性
        // print(this.name);
        print(name);
    
        // 静态方法中不能访问非静态属性
        // print(age);
      }
    }
    
    void main() {
      // 静态成员,可以通过类名直接访问
      print(Person.name); // Rogers
      Person.printName(); // Rogers
    
      // 不能通过类名称,直接访问非静态方法
      // Person.printInfo();
    
      Person p = new Person();
      // 不能通过实例化对象访问静态属性
      // print(p.name);
      p.printInfo();
    }
    元数据

    元数据以 @ 开头,可以给代码标记一些额外的信息
      元数据可以用在库,类,构造器,函数,字段,参数或变量声明的前面

    @override(重写)
      某个方法添加该注解后,表示重写了父类中的同名方法

    @required(必填)
      可以通过 @required 来注解 Dart 中的命名参数,用来指示它是必填参数

    @deprecated(弃用)
      某个类或某个方法加上该注解后,表示这个类或方法不再建议使用
    class Phone {
      // 表示这是旧版本中的开机方法,会在后续的迭代版本中删除
      @deprecated
      activate() {
        turnOn();
      }
    
      turnOn() {
        print('开机');
      }
    }
    
    void main() {
      Phone p = new Phone();
      p.activate();
    }
  • 相关阅读:
    Linux设备驱动阻塞与非阻塞I/O
    Linux设备驱动轮询操作
    Linux设备驱动中的并发控制
    Python趣味入门8:集合变量列表、集合、元组、字典
    买我的《Python青少年趣味编程》给寒假爱编程的小朋友一点温暖。
    第56篇ProfileData与DataLayout
    第59篇编译策略
    第60篇获取编译任务
    第63篇解释器与编译器适配(二)
    第57篇profile实例
  • 原文地址:https://www.cnblogs.com/rogerwu/p/16193664.html
Copyright © 2020-2023  润新知