阿里云主机折上折
  • 微信号
Current Site:Index > Access modifiers (public/private/protected)

Access modifiers (public/private/protected)

Author:Chuan Chen 阅读数:46784人阅读 分类: TypeScript

Access Modifiers (public/private/protected)

Access modifiers in TypeScript are used to control the accessibility of class members, primarily including public, private, and protected. These modifiers determine whether class members can be accessed within the class, in subclasses, or outside the class.

public Modifier

public is the default access modifier. When no modifier is explicitly specified, class members default to public. public members can be accessed inside the class, in subclasses, and outside the class.

class Person {
  public name: string;
  
  constructor(name: string) {
    this.name = name;
  }
  
  public greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

const person = new Person('Alice');
console.log(person.name); // Output: Alice
person.greet(); // Output: Hello, my name is Alice

In this example, the name property and greet method are both public, so they can be accessed directly outside the class.

private Modifier

The private modifier indicates that a member can only be accessed within the class and cannot be accessed in subclasses or outside the class. This helps encapsulate the internal implementation details of the class.

class BankAccount {
  private balance: number;
  
  constructor(initialBalance: number) {
    this.balance = initialBalance;
  }
  
  public deposit(amount: number) {
    if (amount > 0) {
      this.balance += amount;
    }
  }
  
  public getBalance(): number {
    return this.balance;
  }
}

const account = new BankAccount(1000);
account.deposit(500);
console.log(account.getBalance()); // Output: 1500
// console.log(account.balance); // Error: Property 'balance' is private and only accessible within class 'BankAccount'

Here, the balance property is marked as private, so it can only be accessed within the BankAccount class. External code can only manipulate and query the balance through the deposit and getBalance methods.

protected Modifier

The protected modifier indicates that a member can be accessed within the class and in subclasses but cannot be accessed outside the class. This is particularly useful when implementing inheritance.

class Vehicle {
  protected speed: number = 0;
  
  protected accelerate(amount: number) {
    this.speed += amount;
  }
}

class Car extends Vehicle {
  public drive() {
    this.accelerate(10); // Can access protected method in subclass
    console.log(`Driving at ${this.speed} km/h`); // Can access protected property in subclass
  }
}

const car = new Car();
car.drive(); // Output: Driving at 10 km/h
// car.accelerate(5); // Error: Property 'accelerate' is protected and only accessible within class 'Vehicle' and its subclasses
// console.log(car.speed); // Error: Property 'speed' is protected and only accessible within class 'Vehicle' and its subclasses

In the Vehicle class, the speed property and accelerate method are both protected, so they can be accessed in the Car subclass but cannot be accessed directly outside the class.

Access Modifiers in Constructors

In TypeScript, constructor parameters can also use access modifiers, which is actually a shorthand for declaring and initializing class members.

class Student {
  constructor(public id: number, private name: string, protected grade: string) {}
  
  public getInfo() {
    return `ID: ${this.id}, Name: ${this.name}, Grade: ${this.grade}`;
  }
}

const student = new Student(1, 'Bob', 'A');
console.log(student.id); // Output: 1
// console.log(student.name); // Error: Property 'name' is private and only accessible within class 'Student'
// console.log(student.grade); // Error: Property 'grade' is protected and only accessible within class 'Student' and its subclasses
console.log(student.getInfo()); // Output: ID: 1, Name: Bob, Grade: A

In this example, the constructor parameters id, name, and grade use public, private, and protected modifiers, respectively. TypeScript automatically declares these parameters as class members and initializes them.

Access Modifiers and Inheritance

Access modifiers play an important role in inheritance relationships, especially the visibility of protected members in subclasses.

class Animal {
  private secret = "I'm an animal";
  protected name: string;
  
  constructor(name: string) {
    this.name = name;
  }
}

class Dog extends Animal {
  private breed: string;
  
  constructor(name: string, breed: string) {
    super(name);
    this.breed = breed;
  }
  
  public getDescription() {
    return `${this.name} is a ${this.breed}`; // Can access protected name
    // return this.secret; // Error: Property 'secret' is private and only accessible within class 'Animal'
  }
}

const dog = new Dog('Buddy', 'Golden Retriever');
console.log(dog.getDescription()); // Output: Buddy is a Golden Retriever
// console.log(dog.name); // Error: Property 'name' is protected and only accessible within class 'Animal' and its subclasses
// console.log(dog.breed); // Error: Property 'breed' is private and only accessible within class 'Dog'

Access Modifiers and Interface Implementation

When a class implements an interface, the access modifiers must be compatible with the interface definition. All members in an interface are public by default.

interface ILogger {
  log(message: string): void;
}

class ConsoleLogger implements ILogger {
  public log(message: string) {
    console.log(message);
  }
  
  private internalLog(details: string) {
    console.debug(`[DEBUG] ${details}`);
  }
}

const logger = new ConsoleLogger();
logger.log("This is a public message"); // Output: This is a public message
// logger.internalLog("Debug info"); // Error: Property 'internalLog' is private and only accessible within class 'ConsoleLogger'

Access Modifiers and Static Members

Access modifiers can also be applied to static members to control their visibility.

class Configuration {
  private static instance: Configuration;
  public static version: string = "1.0";
  
  private constructor() {}
  
  public static getInstance(): Configuration {
    if (!Configuration.instance) {
      Configuration.instance = new Configuration();
    }
    return Configuration.instance;
  }
}

console.log(Configuration.version); // Output: 1.0
const config = Configuration.getInstance();
// const config2 = new Configuration(); // Error: Constructor of class 'Configuration' is private

Access Modifiers and Abstract Classes

In abstract classes, access modifiers can control the visibility of abstract members.

abstract class Shape {
  protected abstract getArea(): number;
  
  public displayArea() {
    console.log(`Area: ${this.getArea()}`);
  }
}

class Circle extends Shape {
  constructor(private radius: number) {
    super();
  }
  
  protected getArea(): number {
    return Math.PI * this.radius * this.radius;
  }
}

const circle = new Circle(5);
circle.displayArea(); // Output: Area: 78.53981633974483
// circle.getArea(); // Error: Property 'getArea' is protected and only accessible within class 'Shape' and its subclasses

Access Modifiers and Getters/Setters

Access modifiers can be applied to getter and setter methods to control property read/write permissions.

class Temperature {
  private _celsius: number = 0;
  
  public get celsius(): number {
    return this._celsius;
  }
  
  public set celsius(value: number) {
    if (value < -273.15) {
      throw new Error("Temperature cannot be below absolute zero");
    }
    this._celsius = value;
  }
  
  public get fahrenheit(): number {
    return this._celsius * 9/5 + 32;
  }
  
  private set fahrenheit(value: number) {
    this._celsius = (value - 32) * 5/9;
  }
}

const temp = new Temperature();
temp.celsius = 25;
console.log(temp.celsius); // Output: 25
console.log(temp.fahrenheit); // Output: 77
// temp.fahrenheit = 77; // Error: Property 'fahrenheit' is private and only accessible within class 'Temperature'

Access Modifiers and readonly

The readonly modifier can be used with access modifiers to create read-only properties.

class Constants {
  public static readonly PI = 3.14159;
  private static readonly SECRET_KEY = "abc123";
  
  public static getSecretHash(): string {
    return this.SECRET_KEY + "hash";
  }
}

console.log(Constants.PI); // Output: 3.14159
// Constants.PI = 3.14; // Error: Cannot assign to 'PI' because it is a read-only property
console.log(Constants.getSecretHash()); // Output: abc123hash
// console.log(Constants.SECRET_KEY); // Error: Property 'SECRET_KEY' is private and only accessible within class 'Constants'

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.