TypeScript 类:public、private、protected 修饰符
TypeScript 提供了三种访问修饰符,用于控制类成员(属性和方法)的可访问性。合理使用这些修饰符,可以封装内部逻辑,保护数据安全,并定义清晰的对外接口。
1. Public 修饰符:完全开放
public 是 TypeScript 中默认的访问修饰符。如果一个成员没有显式指定修饰符,它就是 public 的。
被标记为 public 的成员可以在任何地方被访问:在类的内部、类的实例上,或者子类中。
- 定义一个带有
public属性的类Person。 - 实例化该类并修改其属性。
class Person {
public name: string; // 显式声明 public
age: number; // 默认也是 public
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public introduce() {
console.log(`My name is ${this.name}, I am ${this.age}.`);
}
}
const person = new Person("Alice", 25);
// 直接访问 public 属性
person.name = "Bob";
person.age = 30;
// 调用 public 方法
person.introduce();
核心结论:当你希望某个属性或方法能够被外部自由读写或调用时,使用 public。
2. Private 修饰符:私有隔离
private 修饰符将成员严格限制在当前类的内部。这意味着:
- 在类外部无法访问该属性或方法。
- 在子类中无法访问该属性或方法。
它主要用于隐藏实现细节,防止外部代码直接修改对象内部状态。
- 创建一个包含
private属性的类BankAccount。 - 尝试在类外部直接修改余额,观察编译器的报错。
class BankAccount {
private balance: number; // 私有属性
constructor(initialBalance: number) {
this.balance = initialBalance;
}
// 提供公共方法来间接操作私有属性
public deposit(amount: number) {
if (amount > 0) {
this.balance += amount;
console.log(`Deposited: ${amount}, New Balance: ${this.balance}`);
}
}
public getBalance() {
return this.balance;
}
}
const myAccount = new BankAccount(100);
// 正确操作:通过公共方法
myAccount.deposit(50);
// 错误操作:直接访问私有属性(编译时报错)
// myAccount.balance = 1000; // Error: Property 'balance' is private and only accessible within class 'BankAccount'.
核心结论:当数据涉及核心逻辑或安全,不应被外部随意篡改时,标记为 private,并通过 public 方法暴露受控的操作接口。
3. Protected 修饰符:受保护的继承
protected 修饰符的行为介于 public 和 private 之间。
- 在类内部可以访问。
- 在子类中可以访问。
- 在类外部(非子类实例)无法访问。
它专门用于继承场景,允许父类定义只有子类才能使用的辅助方法或属性,同时对外部隐藏这些细节。
- 定义一个父类
Employee,包含protected属性。 - 创建子类
Manager,并在子类方法中访问父类的protected成员。 - 实例化
Employee,尝试直接访问该成员,观察报错。
class Employee {
protected name: string;
private salary: number; // 私有,子类也无法访问
constructor(name: string, salary: number) {
this.name = name;
this.salary = salary;
}
protected getDetails() {
return `Name: ${this.name}`;
}
}
class Manager extends Employee {
department: string;
constructor(name: string, salary: number, department: string) {
super(name, salary);
this.department = department;
}
public introduceManager() {
// 子类可以访问 protected 成员
const baseInfo = this.getDetails();
// 子类无法访问 private 成员 (this.salary 是错误的)
return `${baseInfo}, Dept: ${this.department}`;
}
}
const manager = new Manager("Charlie", 5000, "IT");
console.log(manager.introduceManager()); // 正确
// 错误:无法在类外部访问 protected 成员
// console.log(manager.name); // Error: Property 'name' is protected and only accessible within class 'Employee' and its subclasses.
核心结论:当你希望某些功能仅对当前类及其派生类(子类)开放时,使用 protected。
4. 对比与选择指南
为了方便记忆,以下是三种修饰符的访问权限对比表。
| 修饰符 | 类内部访问 | 子类访问 | 类外部(实例)访问 | 主要用途 |
|---|---|---|---|---|
public |
✅ 是 | ✅ 是 | ✅ 是 | 定义对外接口,允许自由读写 |
protected |
✅ 是 | ✅ 是 | ❌ 否 | 供继承体系内部共享,隐藏细节 |
private |
✅ 是 | ❌ 否 | ❌ 否 | 强封装,保护核心状态 |
在实际开发中,遵循以下步骤可以快速做出决定:
- 检查该属性是否需要作为外部 API 的一部分供其他模块使用?如果是,声明为
public。 - 检查该属性是否仅在当前类内部使用,且不希望被子类干扰?如果是,声明为
private。 - 检查该属性是否需要在子类中被复用或重写,但又不希望暴露给外部?如果是,声明为
protected。 - 默认情况下,如果不加修饰符,TypeScript 会将其视为
public,但为了代码可读性,建议显式声明。

暂无评论,快来抢沙发吧!