公有成员与私有成员
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 30 课,共 110 课。
封装是面向对象编程的核心原则之一。它指的是控制对类内部数据的访问,决定哪些内容可以对外公开,哪些内容应该保持隐藏。
在 Dart 中,类成员(字段和方法)默认是公开的。这意味着任何代码都可以直接访问它们:
class BankAccount {
String owner;
double balance;
BankAccount(this.owner, this.balance);
}
var account = BankAccount('Alice', 1000);
account.balance = -500; // 任何人都能直接修改它!这会带来问题。没有任何机制能阻止设置无效的余额。
为了保护内部数据,Dart 使用私有成员。成员名称以下划线 _ 开头时,就会变为私有成员:
class BankAccount {
String owner;
double _balance; // 私有:以下划线开头
BankAccount(this.owner, this._balance);
double get balance => _balance; // 受控访问
}现在,外部无法直接访问定义该类的库中的 _balance。外部代码必须改用公共 getter。这样你就能控制数据的读取和修改方式,确保对象始终处于有效状态。
挑战
简单我们来构建一个简单的密码管理器,演示公有成员和私有成员之间的区别。你将看到,下划线前缀如何保护敏感数据,防止从类的库外部直接访问。
你将创建两个文件来整理代码:
credential.dart:定义一个用于存储网站登录信息的Credential类。这个类应包含:- 一个公有的
String website,任何人都可以看到它对应的网站 - 一个公有的
String username,用户名可以公开显示 - 一个私有的
String _password,实际密码必须受到保护 - 一个接收这三个值的构造函数
- 一个公有的 getter
password,用于返回私有的_password(受控访问) - 一个
getMaskedPassword()方法,将密码中的所有字符替换为星号*(长度与实际密码相同) - 一个
displayCredential()方法,安全地输出凭据的信息(显示掩码后的密码,而不是真实密码)
- 一个公有的
main.dart:导入凭据类,并演示封装如何保护密码:- 为网站
'github.com'、用户名'dev_user'和密码'secret123'创建一个凭据 - 为网站
'email.com'、用户名'john_doe'和密码'myP@ss'创建另一个凭据 - 对于每个凭据,调用
displayCredential(),然后使用公有 getter 访问密码长度,并输出Actual password length: [length]
- 为网站
displayCredential() 方法应按以下格式输出:
--- Credential ---
Website: [website]
Username: [username]
Password: [maskedPassword]预期输出:
--- Credential ---
Website: github.com
Username: dev_user
Password: *********
Actual password length: 9
--- Credential ---
Website: email.com
Username: john_doe
Password: ******
Actual password length: 6亲手试试
import 'credential.dart';
void main() {
// TODO: 为 github.com 创建一个凭据
// 网站:'github.com',用户名:'dev_user',密码:'secret123'
// TODO: 对第一个凭据调用 displayCredential()
// TODO: 使用公共 getter 输出实际密码长度
// 格式:"Actual password length: [length]"
// TODO: 为 email.com 创建一个凭据
// 网站:'email.com',用户名:'john_doe',密码:'myP@ss'
// TODO: 对第二个凭据调用 displayCredential()
// TODO: 使用公共 getter 输出实际密码长度
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器