基本构造函数
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(...)
可视化理解
