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(...)

可视化理解

相关推荐
恋猫de小郭1 小时前
Android 限制侧载新进展,谷歌联合国内厂商推验证计划
android·前端·flutter
恋猫de小郭2 小时前
解读 Android 17 全新内存限制,有没有“豁免”后门?
android·前端·flutter
代码煮茶3 小时前
React 组件封装方法论 —— 以 Todo App 为例
javascript·react.js
任沫4 小时前
Agent之Function Call
javascript·人工智能·go
默_笙5 小时前
🛬 我让 AI 帮我写了一个打飞机游戏,结果 Canvas 把我整不会了
前端·javascript
梯度不陡5 小时前
AI 到底能不能从零写软件?ProgramBench 和 RepoZero 给出了两种答案
前端·javascript·面试
胡萝卜术7 小时前
滑动窗口最大值:从暴力到单调队列,层层优化全解析
前端·javascript·面试
kyriewen8 小时前
2026 年了,这 6 个 npm 包可以卸载了——浏览器原生 API 已经能替代
前端·javascript·npm
铁皮饭盒9 小时前
bun直接tsx,优雅!
javascript·后端
_柳青杨11 小时前
一文吃透 Node.js 事件循环:从原理到 Node 20+ 重大变更
javascript·后端