工厂构造函数
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 14 课,共 110 课。
工厂构造函数是一种特殊的构造函数,不一定总会创建新实例。与普通构造函数不同,工厂构造函数可以返回已有实例、子类型,甚至 null(如果允许为空)。你可以使用 factory 关键字声明它。
class Logger {
static final Logger _instance = Logger._internal();
// 私有命名构造函数
Logger._internal();
// 工厂构造函数
factory Logger() {
return _instance;
}
}
Logger log1 = Logger();
Logger log2 = Logger();
print(identical(log1, log2)); // true在这个示例中,工厂构造函数总是返回同一个实例。无论你调用 Logger() 多少次,得到的都是同一个对象。这种模式通常用于实现单例。
工厂构造函数与普通构造函数的一个关键区别是:它们无法访问 this,因为它们可能根本不会创建新实例。相反,它们必须显式返回一个对象:
class Shape {
factory Shape(String type) {
if (type == 'circle') return Circle();
if (type == 'square') return Square();
return Rectangle();
}
}
class Circle extends Shape { Circle() : super._(); }
class Square extends Shape { Square() : super._(); }
class Rectangle extends Shape { Rectangle() : super._(); }当你需要控制实例的创建方式时,工厂构造函数会很有用,例如返回缓存对象、实现对象池,或根据输入参数决定实例化哪个子类型。
挑战
简单我们来构建一个通知系统,根据简单的字符串输入,使用工厂构造函数创建不同类型的通知。
你将创建两个文件来组织代码:
notification.dart:定义一个Notification类,作为所有通知类型的基类。这个类应包含:- 一个
String message字段 - 一个私有命名构造函数
Notification._internal,用于初始化 message - 一个工厂构造函数
Notification(String type, String message),根据type参数返回不同的通知子类:- 如果 type 是
'email',则返回一个EmailNotification - 如果 type 是
'sms',则返回一个SMSNotification - 否则,返回一个
PushNotification
- 如果 type 是
- 一个
send()方法,用于打印Sending: [message]
- 一个
在同一个文件中,创建三个继承 Notification 的子类:
EmailNotification:重写send(),打印Email: [message]SMSNotification:重写send(),打印SMS: [message]PushNotification:重写send(),打印Push: [message]
每个子类都需要一个接收 message 的构造函数,并通过 super._internal(message) 将它传给父类。
main.dart:导入通知类,并使用工厂构造函数创建三个通知:- 创建一条消息为
'Welcome!'的电子邮件通知 - 创建一条消息为
'Your code is 1234'的 SMS 通知 - 创建一条消息为
'New update available'的推送通知
send()。- 创建一条消息为
预期输出:
Email: Welcome!
SMS: Your code is 1234
Push: New update available亲手试试
import 'notification.dart';
void main() {
// TODO:创建一条电子邮件通知,消息内容为 'Welcome!'
// TODO:创建一条短信通知,消息内容为 'Your code is 1234'
// TODO:创建一条推送通知,消息内容为 'New update available'
// TODO:依次对每条通知调用 send()
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器