Menu
CoddyTech

_ 前缀约定

本课属于 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) { }      // 私有方法
}

在同一个类中,你可以像平常一样访问私有成员。此限制仅适用于库外部的代码。按照这一约定,阅读代码时可以立即看出哪些成员仅供内部使用:所有以 _ 开头的内容都是实现细节。

challenge icon

挑战

简单

让我们为游戏构建一个分数追踪器,演示下划线前缀如何隐藏内部实现细节,同时提供简洁的公共接口。

你将把代码组织到两个文件中:

  • score_tracker.dart:创建一个 ScoreTracker 类,用恰当的封装来管理玩家的分数。这个类应该包含:
    • 一个公共的 String playerName,所有人都能看到正在游戏的玩家
    • 一个初始值为 0 的私有 int _score,原始分数应受到保护
    • 一个初始值为 1 的私有 int _bonusMultiplier,这是游戏内部机制
    • 一个接收玩家姓名的构造函数
    • 一个返回私有 _score 的公共 getter score
    • 一个私有方法 _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]'
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Dart 在线编译器