_ 前缀约定
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 31 课,共 110 课。
下划线前缀 _ 是 Dart 标记成员为私有的方式。与使用 private 等关键字的语言不同,Dart 依靠这种命名约定来控制可见性。
你可以在字段和方法前都加上下划线:
class Counter {
int _count = 0; // 私有字段
void _increment() { // 私有方法
_count++;
}
void increase() { // 公共方法
_increment();
print('Count: $_count');
}
}下划线适用于任何标识符,包括变量、方法、getter、setter,甚至类名。名为 _Helper 的类对其库来说是私有的。
class Person {
String _name; // 私有
int _age; // 私有
Person(this._name, this._age);
String get name => _name; // 公共 getter
void _validateAge(int age) { } // 私有方法
}在同一个类中,你可以像平常一样访问私有成员。此限制仅适用于库外部的代码。按照这一约定,阅读代码时可以立即看出哪些成员仅供内部使用:所有以 _ 开头的内容都是实现细节。
挑战
简单让我们为游戏构建一个分数追踪器,演示下划线前缀如何隐藏内部实现细节,同时提供简洁的公共接口。
你将把代码组织到两个文件中:
score_tracker.dart:创建一个ScoreTracker类,用恰当的封装来管理玩家的分数。这个类应该包含:- 一个公共的
String playerName,所有人都能看到正在游戏的玩家 - 一个初始值为
0的私有int _score,原始分数应受到保护 - 一个初始值为
1的私有int _bonusMultiplier,这是游戏内部机制 - 一个接收玩家姓名的构造函数
- 一个返回私有
_score的公共 getterscore - 一个私有方法
_applyBonus(int points),返回points * _bonusMultiplier - 一个公共方法
addPoints(int points),在内部使用_applyBonus来计算实际增加的分数,更新_score,并打印Added [calculated] points! - 一个公共方法
activateDoubleBonus(),将_bonusMultiplier设为2,并打印Double bonus activated! - 一个公共方法
displayStats(),显示玩家当前的状态
- 一个公共的
main.dart:导入分数追踪器,并模拟一局游戏:- 为玩家
'Alex'创建一个ScoreTracker - 调用
displayStats() - 增加
10分 - 增加
25分 - 激活双倍奖励
- 增加
15分(这应该翻倍) - 调用
displayStats() - 使用公共 getter 打印
Final score: [score]
- 为玩家
displayStats() 方法应该按以下格式打印:
=== Player Stats ===
Player: [playerName]
Current Score: [_score]注意,私有方法 _applyBonus 和字段 _bonusMultiplier 如何在内部处理奖励计算。外部代码只能看到公共方法,并不了解倍率系统,这是由下划线约定隐藏的实现细节。
预期输出:
=== Player Stats ===
Player: Alex
Current Score: 0
Added 10 points!
Added 25 points!
Double bonus activated!
Added 30 points!
=== Player Stats ===
Player: Alex
Current Score: 65
Final score: 65亲手试试
import 'score_tracker.dart';
void main() {
// TODO:为玩家 'Alex' 创建一个 ScoreTracker
// TODO:调用 displayStats()
// TODO:增加 10 分
// TODO:增加 25 分
// TODO:激活双倍奖励
// TODO:增加 15 分(这次应按双倍计算)
// TODO:调用 displayStats()
// TODO:使用公开的 getter 打印 'Final score: [score]'
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器