Menu
CoddyTech

库级别的隐私

本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 32 课,共 110 课。

在 Dart 中,隐私是在库级别强制执行的,而不是在类级别。这与 Java 或 C++ 等语言有一个重要区别。在 Dart 中,库通常是单个文件,也可以是通过 part 指令连接起来的多个文件。

私有成员(以 _ 开头的成员)在同一个库中的任何位置都可以访问,包括在其他类中:

// 两个类都在同一个文件中(属于同一个库)
class Engine {
  int _horsepower = 200;  // 仅限这个库访问
}

class Car {
  void showPower(Engine engine) {
    print(engine._horsepower);  // 可以访问!因为属于同一个库
  }
}

不过,当你从另一个文件导入一个类时,它的私有成员就会真正隐藏起来:

// 文件:engine.dart
class Engine {
  int _horsepower = 200;
  int get power => _horsepower;
}

// 文件:main.dart
import 'engine.dart';

void main() {
  var engine = Engine();
  // print(engine._horsepower);  // 错误!无法访问
  print(engine.power);           // 可以运行:使用公共 getter
}

这种库级隐私意味着同一文件中的类可以密切协作,同时仍对外部代码隐藏实现细节。这是一种有意的设计选择,鼓励你将相关的类组织在同一个库中。

challenge icon

挑战

简单

我们来构建一个团队协作系统,演示 Dart 中库级隐私的工作方式。你将看到,同一文件中的类可以访问彼此的私有成员,而不同文件中的代码则不能。

你将把代码分成两个文件:

  • team.dart:这个文件包含两个在同一个库中紧密协作的类:
    • 一个 Member 类,包含公开的 String name 和私有的 int _performanceScore,初始值为 50。添加一个接收姓名的构造函数,以及一个返回私有分数的公开 getter performanceScore。
    • 在同一文件中添加一个 TeamLead 类,它可以直接访问 Member 的私有字段(因为它们在同一个库中)。这个类应包含公开的 String name、一个接收姓名的构造函数,以及一个方法 evaluateMember(Member member)。该方法直接访问 member._performanceScore,将它加上 10,并打印 [leadName] boosted [memberName]'s score to [newScore]。
  • main.dart:导入你的团队文件,并演示访问方式的区别:
    • 创建一个名为 'Alice' 的 Member
    • 创建一个名为 'Bob' 的 TeamLead
    • 使用 Alice 的公开 getter 打印 Initial score: [score]
    • 让 Bob 使用 evaluateMember 对 Alice 进行评估
    • 使用公开 getter 打印 Updated score: [score]
    • 打印 Direct access from main: Not allowed(这提醒我们,main.dart 不能直接访问 _performanceScore,因为它位于另一个库中)

这里的关键点是,TeamLead 可以直接读取和修改 Member 的私有 _performanceScore,因为这两个类都位于同一个文件中(也就是同一个库中)。不过,main.dart 中的代码必须使用公开 getter,因为它位于另一个库中。

预期输出:

Initial score: 50
Bob boosted Alice's score to 60
Updated score: 60
Direct access from main: Not allowed

亲手试试

import 'team.dart';

void main() {
  // TODO: 创建一个名为 'Alice' 的 Member

  // TODO: 创建一个名为 'Bob' 的 TeamLead

  // TODO: 使用 Alice 的公共 getter 打印 "Initial score: [score]"

  // TODO: 让 Bob 使用 evaluateMember 评估 Alice

  // TODO: 使用公共 getter 打印 "Updated score: [score]"

  // TODO: 打印 "Direct access from main: Not allowed"
  // 注意:这里无法访问 alice._performanceScore,因为
  // main.dart 和 team.dart 属于不同的库
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Dart 在线编译器