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

可视化理解

相关推荐
weixin_52064987几秒前
C#闭包知识点详解
开发语言·c#
东北甜妹5 分钟前
Redis Cluster 操作命令
java·开发语言
花间相见7 分钟前
【大模型微调与部署01】—— ms-swift-3.12入门:安装、快速上手
开发语言·ios·swift
techdashen14 分钟前
Rust 正式成立 Types Team:类型系统终于有了专属团队
开发语言·后端·rust
jiayong2318 分钟前
第 17 课:任务选择与批量操作
开发语言·前端·javascript·vue.js·学习
源码老李24 分钟前
Day 07 · 游戏也要管理状态:场景切换·资源加载·对象池实战
前端·javascript·游戏
量子炒饭大师26 分钟前
【C++11】RAII 义体加装指南 ——【包装器 与 异常】C++11中什么是包装器?有哪些包装器?C++常见异常有哪些?(附带完整代码讲解)
开发语言·c++·c++11·异常·包装器
telllong30 分钟前
Python异步编程从入门到不懵:asyncio实战踩坑指南
开发语言·python
知兀30 分钟前
【Result类】(使用/不使用<T> data的情况);自带静态方法、纯数据类;
java·开发语言
donecoding31 分钟前
遗嘱、水管与抢救室:TS 切入 Go 的流程控制、接口与并发
javascript·typescript·go