Flutter---构造函数

基本构造函数

Dart 复制代码
class Person {
  String name;
  int age;
  
  // 普通构造函数
  Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

 // 简化写法:直接把参数赋值给成员变量
 // Person(this.name, this.age);  // ← 一行搞定!
}

void main() {
  Person p = Person("张三", 25);
  print("${p.name}, ${p.age}");  // 张三, 25
}

命名构造函数

命名构造函数就是有名字的构造函数 ,可以有多个,用 . 区分

Dart 复制代码
class Person {
  String name;
  int age;
  
  // 默认构造函数
  Person(this.name, this.age);
  
  // 命名构造函数1:从地图创建
  Person.fromMap(Map<String, dynamic> map) 
      : name = map['name'],
        age = map['age'];
  
  // 命名构造函数2:从 JSON 创建
  Person.fromJson(String jsonString) 
      : name = "解析出的名字",
        age = 0;
  
  // 命名构造函数3:创建默认人员
  Person.guest() 
      : name = "游客",
        age = 0;
}

void main() {
  // 使用不同的构造函数创建对象
  Person p1 = Person("张三", 25);                    // 普通
  Person p2 = Person.fromMap({'name': '李四', 'age': 30});  // 命名
  Person p3 = Person.guest();                       // 命名
  
  print(p1.name);  // 张三
  print(p2.name);  // 李四
  print(p3.name);  // 游客
}

初始化列表

初始化列表是 : 后面的部分,在构造函数体执行前运行

Dart 复制代码
class Person {
  final String name;  // final 变量必须初始化
  final int age;
  
  // 初始化列表:在构造函数体之前初始化 final 变量
  Person.fromMap(Map<String, dynamic> map) 
      : name = map['name'],      // ← 初始化列表
        age = map['age'] {       // ← 这里不能写赋值了
    // 构造函数体
    print("对象创建完成");
  }
}

初始化列表的优势

Dart 复制代码
class Example {
  final int a;
  int b;
  
  // ❌ 错误:final 变量不能在构造函数体中赋值
  Example(int value) {
    a = value;  // 编译错误!
    b = value;  // 普通变量可以
  }
  
  // ✅ 正确:final 变量必须在初始化列表赋值
  Example(int value) : a = value {  // ← 这里赋值
    b = value;
  }
}

使用super,调用父类构造函数

Dart 复制代码
// 父类
class Animal {
  String type;
  
  Animal(this.type) {
    print("Animal 构造函数");
  }
  
  Animal.named(this.type) {
    print("Animal 命名构造函数");
  }
}

// 子类
class Dog extends Animal {
  String name;
  
  // 调用父类普通构造函数
  Dog(String name, String type) : super(type) {
    this.name = name;
    print("Dog 构造函数");
  }
  
  // 调用父类命名构造函数
  Dog.fromMap(Map<String, dynamic> map) 
      : name = map['name'], //初始化自己的属性
        super.named(map['type']) { //初始化父类的属性
    print("Dog 命名构造函数");
  }
}

void main() {
  Dog d1 = Dog("旺财", "犬科");
  // 输出:
  // Animal 构造函数
  // Dog 构造函数
  
  Dog d2 = Dog.fromMap({'name': '小黑', 'type': '犬科'});
  // 输出:
  // Animal 命名构造函数
  // Dog 命名构造函数
}

疑问点

Dart 复制代码
1.子类为什么要调用父类的构造函数?
答:子类必须调用父类构造函数,因为父类的属性需要被初始化!

2.谁负责初始化父类属性?
父类自己的构造函数

3.子类能直接给父类属性赋值吗?
不能,因为父类属性可能是final

4.怎么调用
在初始化列表中用super(...)

可视化理解

相关推荐
重生之小比特29 分钟前
【C++进阶】异常
开发语言·c++
朝朝辞暮i39 分钟前
C++ 第 15 课:指针 * 和地址 &
开发语言·c++
linux_cfan41 分钟前
videojs v10 源代码系列解读:35 · HLS 解析器:multivariant 与 media playlist
前端·javascript·音视频
奶茶树42 分钟前
【C++】14. C++11新特性【下】
开发语言·c++
web打印社区44 分钟前
汽修 / 4S 店:维修工单、结算单网页怎么静默出纸
开发语言·前端·javascript·chrome·ecmascript
Sirens.1 小时前
Java多线程实例:单例模式、阻塞队列、线程池与定时器
java·开发语言·单例模式
沫璃染墨1 小时前
《从零入门Linux系统篇(五十三):线程篇·六——线程互斥详解:从并发问题到mutex互斥锁》
linux·运维·服务器·开发语言·后端·架构·系统架构
老王爱玩车1 小时前
深入理解指针6
c语言·开发语言·学习
Eloudy1 小时前
全文 - version.A - AMBA CHI Chip-to-Chip(C2C)
java·开发语言·数据库·gpu·chiplet
秋名RG1 小时前
Java历代LTS版本新特性详解(代码增强版)
java·开发语言·python