Appearance
Dart教程 - 7 面向对象(2)
继续讲解面向对象...
7.3 继承
在现实世界,有麻雀和鸽子,它们都属于鸟类,麻雀、鸽子和鸟类的关系是父类和子类的关系。
麻雀和鸽子都会飞,我们可以在麻雀类中定义一个飞的方法,在鸽子类中定义一个飞的方法,但是这两个飞的方法是一样的,都是用翅膀飞。我们可以在鸟类中定义一个飞的方法,让麻雀和鸽子类都继承这个鸟类,那么它们就拥有了飞的方法,就不用再定义了。
1 继承的语法
在Dart中,使用extends关键字实现继承。
dart
class 子类名 extends 父类名 {
类内容
}举个栗子:
麻雀继承鸟类,鸽子继承鸟类:
dart
class Bird {
// 定义一个鸟类
late int age; // 鸟都有年龄
void fly() {
// 定义了一个飞的方法
print("我${this.age}岁了,我会飞");
}
void tweet() {
// 定义了一个叫的方法
print("我会叫");
}
}
class Sparrow extends Bird {
// 定义一个麻雀类,继承自鸟类
}
class Pigeon extends Bird {
// 定义一个鸽子类,继承自鸟类
}
void main() {
Sparrow sparrow = Sparrow(); // 创建一个麻雀对象
sparrow.age = 1;
sparrow.fly();
sparrow.tweet();
Pigeon pigeon = Pigeon(); // 创建一个鸽子对象
pigeon.age = 2;
pigeon.fly();
pigeon.tweet();
}在上面的代码中,我们先定义了一个鸟类,然后在鸟类中定义了 age属性 ,并定义了两个方法 fly方法和 tweet方法;
然后定义类麻雀类,继承鸟类,那么就拥有了鸟类的属性和方法。鸽子类也同样。
执行结果:
我1岁了,我会飞
我会叫
我2岁了,我会飞
我会叫注意,继承不能继承父类私有的成员变量和方法。
如果父类的成员变量和属性不想被子类继承,可以设置为私有成员。
一个类如果没有写明继承哪个类,那么默认都是集成自Object类,所以最终的结果就是Object类是所有类的父类!
2 复写父类方法
所以继承父类就拥有了父类非私有的成员变量和方法,如果父类不是我想要的方法,我还可以进行覆盖。
例如,鸟类提供了叫的方法,但是我麻雀有自己的叫法,我要啾啾叫,那么我们可以重写父类的方法,实现自己的个性化。
dart
class Bird {
// 定义一个鸟类
late int age; // 鸟都有年龄
void fly() {
// 定义了一个飞的方法
print("我${this.age}岁了,我会飞");
}
void tweet() {
// 定义了一个叫的方法
print("我会叫");
}
}
class Sparrow extends Bird {
// 定义一个麻雀类,继承自鸟类
void tweet() {
print("我会啾啾叫");
}
}
class Pigeon extends Bird {
// 定义一个鸽子类,继承自鸟类
}
void main() {
Sparrow sparrow = Sparrow(); // 创建一个麻雀对象
sparrow.age = 1;
sparrow.fly();
sparrow.tweet();
Pigeon pigeon = Pigeon(); // 创建一个鸽子对象
pigeon.age = 2;
pigeon.fly();
pigeon.tweet();
}执行结果:
我1岁了,我会飞
我会啾啾叫
我2岁了,我会飞
我会叫那么如果我在父类的fly()方法中调用tweet()方法,然后子类方法调用fly()方法,那么会如何执行呢?
dart
class Bird {
void fly() {
// 定义了一个飞的方法
print("我会飞");
tweet();
}
void tweet() {
// 定义了一个叫的方法
print("我会叫");
}
}
class Sparrow extends Bird {
void tweet() {
print("我会啾啾叫");
}
}
void main() {
Sparrow sparrow = Sparrow(); // 创建一个麻雀对象
sparrow.fly();
}sparrow.fly() 调用的是继承自父类的方法,在 fly() 方法中调用了 tweet() 方法,那么调用的是父类的tweet() 方法还是子类的tweet() 方法呢?
是调用子类的方法。
执行结果:
我会飞
我会啾啾叫3 调用父类方法
我们在重写父类方法的时候,应该尽量做到在父类方法的基础上进行扩展。
所以很有可能需要调用父类被重写的方法,然后在父类原来的方法上进行扩展。
那么如果我们想要在子类中调用父类被重写的属性和方法呢?
使用 super 关键字来调用父类的属性或方法。
举个栗子:
dart
class Bird {
// 定义一个鸟类
int age = 1; // 鸟都有年龄
void fly() {
// 定义了一个飞的方法
print("我${this.age}岁了,我会飞");
}
void tweet() {
// 定义了一个叫的方法
print("我会叫");
}
}
class Pigeon extends Bird {
late int age;
// 定义一个鸽子类,继承自鸟类
void tweet() {
// 重写了父类叫的方法
print("我会咕咕叫");
}
void test() {
print("age:${super.age}"); // 调用父类的属性
super.tweet(); // 调用父类的方法
print("age:${this.age}");
this.tweet();
}
}
void main() {
Pigeon pigeon = Pigeon(); // 创建一个鸽子对象
pigeon.age = 10;
pigeon.test();
}上面子类中定义了一个和父类中相同名称的属性age,如果要在子类中调用父类的属性 ,可以通过 super.父类属性 来调用,同样,如果要在子类中调用父类的方法,可以通过 super.父类方法() 来调用。
执行结果:
age:1
我会叫
age:10
我会咕咕叫4 构造函数的继承
子类继承父类,是没办法直接继承构造函数的。
但是子类的构造函数是会隐式的调用的无参构造函数。
举个栗子:
dart
class Bird {
late int age;
Bird() {
print("执行了 Bird 构造函数");
}
}
class Pigeon extends Bird {
Pigeon() {
print("执行了 Pigeon 构造函数");
}
Pigeon.fromName(String name) {
print("执行了 fromName 明明构造函数");
}
}
void main() {
Pigeon(); // 创建对象,没有传入参数
Pigeon.fromName("DouBi");
}执行结果:
执行了 Bird 构造函数 执行了 Pigeon 构造函数 执行了 Bird 构造函数 执行了 fromName 明明构造函数
通过结果可以看到,子类的构造函数会先调用父类的无参构造函数。
如果父类定义了有参的构造函数,那么就没有无参的构造函数了,那么就会报错。
举个栗子:
dart
class Bird {
late int age;
Bird(this.age); // 定义了有参的构造函数
}
class Pigeon extends Bird {}上面的代码是会报错的,因为Pigeon类没有写构造函数,使用的是无参构造函数,执行的时候会调用父类Bird的无参构造函数,但是Bird类没有无参构造函数,所以会报错。
所以我们在写Pigeon类的构造函数的时候,要显式的调用父类的构造函数。
调用父类的构造函数需要在构造函数的初始化列表中使用super()来调用:
dart
class Bird {
late int age;
Bird(this.age); // 定义了有参的构造函数
}
class Pigeon extends Bird {
Pigeon(int age) : super(age); // 使用super调用父类的构造函数
}我们还可以调用父类的命名构造函数:
dart
class Bird {
late int age;
Bird(this.age);
Bird.fromMap(Map<String, Object> map) : this.age = map['age'] as int;
}
class Pigeon extends Bird {
Pigeon(int age) : super(age); // 使用super调用父类的构造函数
// 调用父类的命名构造函数
Pigeon.fromMap(Map<String, Object> map) : super.fromMap(map) {
}
}5 类型判断
我们可以判断某个对象的类型,以及是否是某个对象的实例。
首先有如下代码:
dart
class Bird {
// 鸟类
}
class Sparrow extends Bird {
// 麻雀类,继承自鸟类
}
class Pigeon extends Bird {
// 鸽子类,继承自鸟类
}runtimeType属性
dart中,可以使用 runtimeType 判断某个对象是否是某个类型,注意:子类的对象不是父类的对象的类型。
举个栗子,基于上面的代码:
dart
void main() {
Pigeon pigeon = Pigeon();
Sparrow sparrow = Sparrow();
print(pigeon.runtimeType); // 输出: Pigeon
print(sparrow.runtimeType); // 输出: Sparrow
print(pigeon.runtimeType == Pigeon); // true,鸽子对象的类型是鸽子
print(pigeon.runtimeType == Bird); // false,鸽子对象的类型不是鸟
print(sparrow.runtimeType == Sparrow); // true,麻雀对象的类型是麻雀
}is 关键字
is 关键字可以判断某个对象是否是某个类型的实例,子类对象也是父类对象的实例。
举个例子,基于上面的代码:
dart
void main() {
Pigeon pigeon = Pigeon();
print(pigeon is Pigeon); // true,鸽子对象是鸽子类型的实例
print(pigeon is Bird); // true,鸽子对象是鸟类的实例
print(pigeon is Sparrow); // false,鸽子对象不是麻雀类的实例
}6 Mixins
我现在是一只鸡,我也想继承鸟类,但是我是家禽,我还想继承家禽类。
那么就需要用到多继承。
在C++、Python中是支持多继承的,但是在Dart中是不支持多继承的。
在Dart中,新增了一种复用代码的机制Mixins,中文意思是混入,允许你在类中重用其他类的代码,而无需继承这些类。它提供了一种灵活的方式来组合和共享功能,以实现代码重用和组合。
在Dart中,有两种方式可以定义Mixin:使用关键字mixin定义Mixin和使用 class 定义一个类。
举个栗子:
下面使用 class 定义了一个家禽类
dart
class Bird {
// 定义一个鸟类
late int age; // 鸟都有年龄
void fly() {
// 定义了一个飞的方法
print("我${this.age}岁了,我会飞");
}
}
class Poultry {
// 定义一个家禽类
late int number; // 家禽需要编号
void eat() {
// 定义了一个吃的方法
print("我吃饭啦");
}
}
class Chicken extends Bird with Poultry {
// 定义一个鸡类,继承自鸟类和家禽类
void fly() {
print("我不会飞");
}
}
void main() {
Chicken chicken = Chicken(); // 创建一个鸡对象
chicken.age = 1;
chicken.number = 9527;
chicken.fly();
chicken.eat();
}然后我们在 Chicken 类上继承了Bird 类,然后使用 with 关键字将 Poultry 家禽类混入到Chicken 类中。
这样就 Chicken 类就可以访问和使用Poultry 家禽类中的属性和方法。
上面定义 Poultry 家禽类,还可以使用关键字mixin 来定义:
dart
mixin Poultry {
// 定义一个家禽类
late int number; // 家禽需要编号
void eat() {
// 定义了一个吃的方法
print("我吃饭啦");
}
}那么使用 class 关键字和使用 mixin 关键字定义混入有什么区别呢?
使用mixin关键字定义Mixin:Mixin类不能直接被实例化,而是通过混入到其他类中来复用其方法和属性。这意味着Mixin类不能有构造函数,并且不能作为独立的类来使用。使用mixin关键字定义Mixin可以更明确地表达其用途(就是用来被混入的),而使用class关键字定义Mixin则与普通类的定义方式更一致。另外,mixin类只能继承自Object,不能继承其他类。
在使用的时候,一个类是可以混入多个类的。如果混入的多个类中存在相同的属性或方法,那么哪一个类中的方法生效呢?
当一个类混入多个类并且这些混入类中存在相同属性或方法时,方法解析的顺序遵循"最后声明的优先"原则。也就是说,最后一个混入的类中的方法将覆盖之前混入的类中的属性和方法。
举个栗子:
dart
mixin A {
int value = 1;
void foo() {
print('A foo');
}
}
mixin B {
int value = 2;
void foo() {
print('B foo');
}
}
class C with A, B {
void test() {
foo(); // 解析为 B 中的 foo 方法
}
void testValue() {
print(value);
}
}
void main() {
var c = C();
c.test(); // 输出: B foo
c.testValue(); // 输出: 2
}在上面的示例中,我们定义了两个Mixin类:A和B,它们都包含一个名为foo的方法。然后,我们创建了一个名为C的类,使用with关键字将A和B混入到C中。
在C类中的test方法中调用了foo方法。由于B是最后一个混入的类,所以方法解析的顺序从右到左,即先在B中查找同名方法。因此,最终调用的是B中的foo方法,输出结果为"B foo"。
同样的,打印value属性,打印的是后混入的B类中的属性。
7.4 多态
1 什么是多态
多态就是多种状态,同一个类型的父类型对象,因为指向的是不同的子对象,而表现出的不同的状态。
所以多态是建立在继承的基础之上的。
举个栗子:
dart
class Bird {
void tweet() {}
}
class Sparrow extends Bird {
void tweet() {
print("我会啾啾叫");
}
}
class Pigeon extends Bird {
void tweet() {
print("我会咕咕叫");
}
}
void main() {
Bird bird1 = Sparrow(); // 创建一个麻雀对象
Bird bird2 = Pigeon(); // 创建一个鸽子对象
bird1.tweet();
bird2.tweet();
}上面麻雀类和鸽子类都继承自鸟类,然后创建了一个麻雀对象和鸽子对象,都赋给了鸟类,通过两个对象分别调用tweet()方法。
执行结果:
我会啾啾叫
我会咕咕叫虽然两个都是鸟类的变量,执行的都是tweet()方法,但是因为是不同的子类对象,却得到不同的结果。
以父类做定义声明,以子类做实际的工作,用于获取同一个行为的不同状态,这就是多态。
那也没看出多态有什么用啊。
多态的作用:
- 提高代码的维护性
- 提高代码的扩展性
- 把不同的子类对象当做父类来看待,可以屏蔽不同子类对象之间的差异,写出通用的代码,以适应需求的不断变化。
2 多态的使用
说了那么多,有点虚,举个栗子:
实现一个功能:学生做交通工具去某个地方,交通工具可能是汽车、飞机。
先定一个汽车类:
传入一个目的地,就可以开车去了。
dart
class Car {
void run(String destination) {
print("开车去->${destination}");
}
}再定义一个飞机类:
dart
class Plane {
void fly(String destination) {
print("飞去->${destination}");
}
}然后定义一个学生类:
dart
class Student {
void go_to(var vehicle, String destination) { // 传入交通工具
if (vehicle.runtimeType == Car) { // 判断交通工具的类型,然后调用交通工具的方法
vehicle.run(destination);
} else if (vehicle.runtimeType == Plane) {
vehicle.fly(destination);
}
}
}学生类有一个go_to()方法,接收交通工具和目的地,然后在方法中判断交通工具的类型,然后调用交通工具的方法。
调用代码:
dart
void main(List<String> args) {
Student stu = Student();
Car car = Car();
Plane plane = Plane();
stu.go_to(car, "北京");
stu.go_to(plane, "新疆");
}执行结果:
开车去->北京
飞去->新疆上面的代码可以实现功能,但是不易于扩展,如果我们现在增加一个交通工具火车,则还需要修改Student类的go_to()方法,针对新的交通工具来处理,因为学生类和汽车、飞机类直接存在依赖关系,耦合性高。

这样是违反了设计原则中的开闭原则,对扩展是开放的,对修改是封闭的,也就是允许在不改变它代码的前提下变更它的行为。
所以上面的代码扩展性就比较差了,那么怎么来优化代码,降低代码的耦合性呢?
这就需要用到多态了。
首先定义一个父类Vehicle(交通工具类),并定义一个transport()方法,都是交通工具,都是运输功能嘛。
然后让Car类和Plane类都继承这个父类,因为不同的子类运输方式不一样,所以子类需要重写父类的方法,实现自己的功能。
dart
class Vehicle {
void transport(String destination) {}
}
class Car extends Vehicle {
void transport(String destination) {
print("开车去->${destination}");
}
}
class Plane extends Vehicle {
void transport(String destination) {
print("飞去->${destination}");
}
}然后修改学生类:
dart
class Student {
void go_to(Vehicle vehicle, String destination) {
vehicle.transport(destination);
}
}学生类只需要调用交通工具的运输功能就可以了。
调用的代码不变:
dart
void main(List<String> args) {
Student stu = Student();
Car car = Car();
Plane plane = Plane();
stu.go_to(car, "北京");
stu.go_to(plane, "新疆");
}执行结果:
开车去->北京
飞去->新疆上面的代码使用了多态,学生类与各个交通工具子类已经不直接产生关系,遵从了设置原则中的依赖倒置原则(程序依赖于抽象接口,不要依赖于具体实现)。

此时如果新增一个火车的交通工具,不用再修改学生类的代码,代码耦合性大大降低。
3 抽象类
什么是抽象类?
含有抽象方法的类成为抽象类。
那什么是抽象方法?
抽象方法就是没有方法体,方法体为空的方法。
上面的 Vehicle 类中的 transport 方法,没有方法体,我们可以将它定义为一个抽象方法,将 Vehicle 定义为抽象类 。
在 class 前面加上 abstract 关键字,就是定义了抽象类。
dart
abstract class Vehicle {
void transport(destination);
}抽象类中也可以包含非抽象方法,子类继承抽象类需要实现(重写)抽象类中所有的抽象方法。
抽象类有什么作用呢?
抽象类是不能被实例化的,也就是不能用来创建对象。一般抽象类都是作为父类使用的,父类用来确定有哪些方法,相当于用来确定设计的标准,用于对子类的约束。
子类用来实现父类的标准,负责具体的实现,配合多态使用,获得不同的工作状态。
4 接口
如果一个抽象类中的方法都是抽象方法,我们可以将这个抽象类定义成接口。
在Java中,定义接口使用 interface 关键字,和定义抽象类是不同的。但是在Dart中,并没有专门的关键字来定义接口。在Dart 中的接口就是通过类来实现的。所以一个抽象类是接口还是抽象来要看怎么使用,通过 extends 来继承就是抽象类,通过 implements 来实现就是接口
举个栗子:
dart
// 定义一个抽象类
abstract class Bird {
void tweet();
}
// 定义一个接口
abstract class Animal {
void breathe();
}
// 定义一个接口
abstract class Helpful {
void help();
}
class Sparrow extends Bird implements Animal, Helpful {
@override
void breathe() {
print("我要呼吸");
}
@override
void tweet() {
print("我会啾啾叫");
}
@override
void help() {
print("有益的");
}
}
void main() {
Animal animal = Sparrow();
animal.breathe();
}上面我们定义了一个抽象类 Bird ,和两个接口 Animal 、Helpful。
然后定义了一个 Sparrow 类作为子类继承 Bird 类,同时实现了 Animal、Helpful两个接口。此时才看出抽象类和接口的不同,也就是说接口的定义是隐式的。
一个类只能有一个父类,但是可以有多个接口。一个类需要实现抽象类和接口中所有的抽象方法,否则编译会报错。
接口中只能定义常量和抽象方法,所以抽象类的作用主要是提供约束和规范。
结合前面多态的使用去理解,前面多态的使用中,使用的是父类来完成的,我们也可以使用接口来完成。
代码:
dart
abstract class Vehicle { // 定义交通工具的接口,所有的交通工具都需要实现该接口
void transport(String destination);
}
class Car implements Vehicle { // 需要实现交通工具接口
void transport(String destination) {
print("开车去->${destination}");
}
}
class Plane implements Vehicle { // 需要实现交通工具接口
void transport(String destination) {
print("飞去->${destination}");
}
}
class Student {
void go_to(Vehicle vehicle, String destination) { // 传入的参数是交通工具,交通工具都必须有transport()方法
vehicle.transport(destination);
}
}
void main(List<String> args) {
Student stu = Student();
Car car = Car();
Plane plane = Plane();
stu.go_to(car, "北京");
stu.go_to(plane, "新疆");
}7.5 类与类的关系
类与类有以下几种关系:
泛化
子类与父类的关系,B类泛化A类,B类是A类的一种。
场景:B类继承A类。
关联
部分与整体的关系,A与B关联,B是A的一部分。
场景:在A类中包含B类型的属性。
依赖
合作关系,A类依赖B类,A的某些功能需要靠B类实现。
场景:B类型作为A类中方法的参数,并不是A的成员。
7.6 数据与JSON的转换
1 JSON 简介
什么是JSON?
JSON就是特定格式的字符串。我们可以将数据按照这个格式进行封装,然后可以在不同的语言和系统之间进行传送和交互。
JSON的2种格式:
格式一:
是一个对象格式的结构。{} 括起来,其中是属性。
json
{
key1:value1,
key2:value2,
...
}举个栗子,以下是一个学生信息的JSON格式,和Python中的字典格式是一样的:
json
{
"sid": "001",
"name": "zhangsan",
"age": 18
}格式二:
外部是一个列表格式的结构,内部是一个个的对象格式的数据。
json
[
{
key1:value1,
key2:value2
},
{
key3:value3,
key4:value4
}
]举个栗子,以下是一个学生信息的列表
json
[{
"sid": "S001",
"name": "zhangsan",
"age": 18
},
{
"sid": "S002",
"name": "lisi",
"age": 19
},
{
"sid": "S003",
"name": "wangwu",
"age": 17
}
]JSON格式是可以相互嵌套的,属性中可以再嵌套JSON。
2 字典转JSON
- 使用
jsonEncode()函数将字典转换为 JSON 字符串。
举个栗子:
需要引入 dart:convert 包。
dart
import 'dart:convert';
void main() {
Map<String, dynamic> data = {
'name': '逗比',
'age': 25,
};
String jsonString = jsonEncode(data);
print(jsonString);
}执行结果:
{"name":"逗比","age":25}3 JSON转字典
- 使用
jsonDecode()函数将 JSON 字符串解析为 Dart 中的字典(Map)。 - 返回的对象类型为
Map<String, dynamic>。
举个栗子:
dart
import 'dart:convert';
void main() {
String jsonString = '{"name": "逗比", "age": 25}';
Map<String, dynamic> data = jsonDecode(jsonString);
print(data['name']);
print(data['age']);
}执行结果:
逗比
254 对象转JSON
举个栗子:
dart
import 'dart:convert';
class Person {
String name;
int age;
Person(this.name, this.age);
Map<String, dynamic> toJson() {
return {
'name': name,
'age': age,
};
}
}
void main() {
Person person = Person('逗比', 25);
String jsonString = jsonEncode(person.toJson());
print(jsonString);
}我们需要先获取对象的字典格式的数据,所以在对象中定义了一个toJson()方法,返回字典数据,然后再通过jsonEncode()函数,将字典转换为JSON字符串:
5 JSON转对象
举个栗子:
dart
import 'dart:convert';
class Person {
String name;
int age;
Person(this.name, this.age);
factory Person.fromJson(Map<String, dynamic> json) {
return Person(json['name'], json['age']);
}
}
void main() {
String jsonString = '{"name": "逗比", "age": 25}';
// 先将Json 转换为字典
Map<String, dynamic> data = jsonDecode(jsonString);
// 使用工厂构造函数将字典转换为对象
Person person = Person.fromJson(data);
print(person.name);
print(person.age);
}一般将JSON转换为字典就可以获取到数据了,如果有特殊的需求,再将字典转换为对象。
首先将JSON字符串转换为字典,然后通过工厂构造函数通过字典构建对象。
执行结果:
逗比
256 列表转JSON
简单数据格式的列表转换为JSON
举个栗子:
dart
import 'dart:convert';
void main() {
List<String> names = ['逗比', '二比', '牛比'];
String jsonString = jsonEncode(names);
print(jsonString);
}直接调用 jsonEncode() 函数进行转换即可。
执行结果:
["逗比","二比","牛比"]如果是对象列表呢?
对象列表转换为JSON
也是调用 jsonEncode() 函数,直接传入列表对象,jsonEncode() 函数会自动调用对象的 toJson() 方法,如果类中没有定义 toJson() 会报错。
举个栗子:
dart
import 'dart:convert';
class Person {
String name;
int age;
Person(this.name, this.age);
Map<String, dynamic> toJson() {
return {
'name': name,
'age': age,
};
}
}
void main() {
List<Person> personList = [];
personList.add(Person("逗比", 12));
personList.add(Person("二比", 13));
personList.add(Person("牛比", 14));
String jsonString = jsonEncode(personList);
print(jsonString);
}7 JSON转列表
简单数据格式的JSON转列表
举个栗子:
dart
import 'dart:convert';
void main() {
String jsonString = '["逗比", "二比", "牛比"]';
List<dynamic> myList = jsonDecode(jsonString);
print(myList); // 输出:[逗比, 二比, 牛比]
}直接调用 jsonDecode() 方法转换为 List<dynamic>。
JSON转换为对象列表
举个栗子:
dart
import 'dart:convert';
class Person {
String name;
int age;
Person(this.name, this.age);
factory Person.fromJson(Map<String, dynamic> json) {
return Person(json['name'], json['age']);
}
}
void main() {
String jsonString = '[{"name":"逗比","age":12},{"name":"二比","age":13},{"name":"牛比","age":14}]';
// 首先将JSON转换为List<dynamic>
List<dynamic> jsonDynamicList = jsonDecode(jsonString);
// 然后遍历List<dynamic> 将其中的元素分别转换为Person对象
List<Person> personList =
jsonDynamicList.map((json) => Person.fromJson(json)).toList();
for (var person in personList) {
print('Name: ${person.name}, Age: ${person.age}');
}
}首先还是需要在类中定义工厂构造函数。
然后在转换的时候,先将JSON转换为 List<dynamic> 列表,这个时候列表中的元素是一个个Map类型的字段元素。所以需要遍历 List<dynamic> ,将其中的字典元素转换为 Person 对象,上面使用的是map 函数。
所以一个类如果要与JSON字符串实现相互转换,需要实现 toJson()方法 和 通过字典转换为对象的工厂构造方法。