JHHK

欢迎来到我的个人网站
行者常至 为者常成

3 对象类型

目录

对象

一、普通对象

class Person {
  String name;
  int age;
  final bool? sexy; //final修饰的属性必须有初始值
  String? _hobby; //私有属性外部无法访问
  int? _height;
  static int? num; //静态属性

  //默认构造函数
  // Person();

  //构造函数:在形参的位置,只有构造函数能使用this
  // : 初始化列表,可以对final修饰的属性赋值,可以进行一些数据的校验
  Person(this.name, this.age) : sexy = true, assert(age >= 0);

  //相当于下面
  // Person (String name, int age) {
  //   this.name = name;
  //   this.age = age;
  // }

  //命名构造函数
  //Flutter中的命名构造函数允许你在一个类中定义多个构造函数,以提供更多的创建对象的选项,使得代码更加灵活和易于维护。
  Person.all(this.name, this.age, this._height, this._hobby) : sexy = true;

  void run() {
    debugPrint('$name 跑起来了');
  }

  void setHobby(String hobby) {
    _hobby = hobby;
  }

  String getHobyy() {
    return _hobby ?? '';
  }

  //私有方法,外部无法访问
  int _getHeight() {
    return _height ?? 0;
  }

  //静态方法
  static addNum(int a) {
    num = num ?? 0 + a;
  }

  //计算属性
  /// 计算属性有以下几点特点:
  /// 它们不存储数据,而是在需要时根据现有数据进行计算。
  /// 计算属性的定义以get关键字开始,后面是属性的名字,没有参数列表。
  /// 计算属性的访问方式与普通属性相同,不需要使用括号。
  int get nianlingChengShengao {
    return age * (_height ?? 0);
  }

  // 操作符
  bool operator >(Person other) {
    return age > other.age;
  }

  @override
  String toString() {
    return 'name: $name, age: $age, height: ${_getHeight()}';
  }
}

普通对象的使用

Person p = Person('xiaoming', 18);
Person p1 = Person.all('xiaoming', 18, 180, 'basketball');
debugPrint('p.name = ${p.name}, p.age = ${p.age}');
p.run();
debugPrint('------------------------------------');
debugPrint('$p');
debugPrint('------------------------------------');
debugPrint(p.getHobyy());
p.setHobby('basketball');
debugPrint(p.getHobyy());
debugPrint('----------------静态属性和方法--------------------');
debugPrint('${Person.num}');
debugPrint('${Person.addNum(10)}');
debugPrint('${Person.num}');
debugPrint('------------------计算属性------------------');
debugPrint('${p.nianlingChengShengao}');
debugPrint('------------------操作符------------------');
Person p2 = Person('tom', 17);
debugPrint('${p > p2}');

类型转换

var obj = Object();
obj = Person('xiaoming', 18);

//类型判断
if (obj is Person) {
    obj.run();// xiaoming 跑起来了
}

//强制类型转换
(obj as Person).run();// xiaoming 跑起来了

二、常量对象

class Person {
  final String name;
  final int age;
  //当一个对象所有的成员属性都是final的时候,那么这个对象可以被创建为常量对象,使用const修饰构造函数。
  const Person(this.name, this.age);
}

三、单例对象

class XYManager {
  static XYManager? _instance;
  //构造函数要想显示返回,需要在前边使用 factory 关键字
  factory XYManager() {
    _instance ??= XYManager._init();
    // if (_instance == null) {
    //   _instance =  XYManager._init();
    // }
    return _instance!;
  }

  //私有的命名构造函数
  XYManager._init();
}

使用

//单例对象的验证
var manager = XYManager();
var manager2 = XYManager();
debugPrint('${manager == manager2}');

类的继承

class Student extends Person {
  /* Dart中的继承
   * 使用extends继承一个类
   * 子类会继承除了构造方法以外的属性和方法
   * Dart是单继承的
   */

  final int schoolNum;

  Student(String name, int age)
      : schoolNum = 0,
        super(name, age); //super调用需要在初始化列表的最后位置

  Student.allProperty(String name, int age, int height, String hobby)
      : schoolNum = 0,
        super.all(name, age, height, hobby);

  void study() {
    debugPrint('一个名字叫$name的学生,正在学习');
  }

  @override //重写父类方法
  void run() {
    debugPrint('一个名字叫$name的学生,正在奔跑');
  }
}

使用

Student st = Student('xiaoming', 18);
st.run();// 一个名字叫xiaoming的学生,正在奔跑

抽象类

在Dart语言中,可以使用abstract关键字来声明一个抽象类
抽象类不能直接实例化,只能用作其他类的基类。
抽象类可以包含抽象方法,这些方法没有具体的实现。
子类继承抽象类后,必须实现抽象类中的所有抽象方法,除非该子类也是一个抽象类。
抽象类中也可以有普通的实例方法,不一定都是抽象方法。

abstract class Animal {
  String? name;
  //抽象方法
  void makeSound();

  //实例方法:可以作为默认实现
  void run() {
    debugPrint('正在跑动');
  }
}

class Dog extends Animal {
  @override
  void makeSound() {
    debugPrint("汪汪汪!");
  }

  @override
  void run() {
    debugPrint('一只叫$name的狗正在跑动');
  }
}

使用

Dog dog = Dog();
dog.name = 'xiaohei';
dog.makeSound();// 汪汪汪!
dog.run();// 一只叫xiaohei的狗正在跑动

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.