Access Modifiers

Chapter: Classes and Objects / Section: Class Fundamentals

Access Modifiers in Typescript: Mastering Public, Private, and Protected

A comprehensive guide to Access Modifiers in Typescript. Learn about controlling access to class members with clear explanations. Perfect for beginners starting with Typescript.

Introduction

Access modifiers are a fundamental concept in object-oriented programming, and Typescript provides robust support for controlling access to class members. By using access modifiers, you can specify which parts of your code can access and modify class properties and methods. This helps maintain encapsulation, improves code security, and prevents unintended modifications. In this article, we'll dive deep into the three main access modifiers in Typescript: public, private, and protected.

Core Concepts

In Typescript, there are three access modifiers:

  1. public: Class members declared as public are accessible from anywhere, both within and outside the class. This is the default access modifier if none is specified.

  2. private: Class members declared as private are only accessible within the class itself. They cannot be accessed or modified from outside the class, even by subclasses.

  3. protected: Class members declared as protected are accessible within the class and its subclasses, but not from outside the class hierarchy.

Here's an example that demonstrates the usage of access modifiers:

class Person { public name: string; private age: number; protected email: string; constructor(name: string, age: number, email: string) { this.name = name; this.age = age; this.email = email; } public greet() { console.log(`Hello, my name is ${this.name}`); } private getAge() { return this.age; } protected sendEmail() { console.log(`Sending email to ${this.email}`); } }

Implementation Details

To use access modifiers in your Typescript classes, follow these steps:

  1. Declare class properties with the appropriate access modifier (public, private, or protected) before the property name.

  2. Declare class methods with the appropriate access modifier before the method name.

  3. Access public members directly using dot notation, such as person.name or person.greet().

  4. Access private members only within the class itself. Attempting to access them outside the class will result in a compile-time error.

  5. Access protected members within the class and its subclasses. Subclasses can access and modify protected members using the this keyword.

Best Practices

  • Use private for class members that should not be accessible from outside the class. This encapsulates internal state and prevents unintended modifications.

  • Use protected for class members that need to be accessible by subclasses but not from outside the class hierarchy.

  • Use public for class members that can be safely exposed and accessed from anywhere.

  • Prefer the least permissive access modifier that fulfills your requirements to maintain encapsulation and minimize unnecessary exposure.

Common Pitfalls

  • Avoid using public for all class members by default. Carefully consider which members should be exposed and which should be encapsulated.

  • Be cautious when modifying private or protected members in subclasses, as it can lead to unexpected behavior if not handled properly.

  • Remember that Typescript's access modifiers are enforced at compile-time, not runtime. JavaScript code can still access and modify class members regardless of their access modifiers.

Practical Examples

Here's an example that demonstrates the use of access modifiers in a real-world scenario:

class BankAccount { private balance: number; constructor(initialBalance: number) { this.balance = initialBalance; } public deposit(amount: number) { this.balance += amount; console.log(`Deposited ${amount}. New balance is ${this.balance}`); } public withdraw(amount: number) { if (amount <= this.balance) { this.balance -= amount; console.log(`Withdrawn ${amount}. New balance is ${this.balance}`); } else { console.log("Insufficient funds"); } } protected getBalance() { return this.balance; } } class SavingsAccount extends BankAccount { private interestRate: number; constructor(initialBalance: number, interestRate: number) { super(initialBalance); this.interestRate = interestRate; } public addInterest() { const interest = this.getBalance() * this.interestRate; this.deposit(interest); } }

In this example, the BankAccount class has a private balance property to encapsulate the account balance. The deposit and withdraw methods are public, allowing external code to perform transactions. The getBalance method is protected, accessible only within the class and its subclasses.

The SavingsAccount class extends BankAccount and adds a private interestRate property. It can access the protected getBalance method to calculate and add interest to the account.

Summary and Next Steps

Access modifiers are a powerful feature in Typescript that enable you to control access to class members. By using public, private, and protected, you can specify which parts of your code can access and modify class properties and methods. This promotes encapsulation, improves code security, and helps maintain a robust class design.

To further enhance your understanding of access modifiers and Typescript classes, consider exploring the following topics:

  • Readonly properties and accessors
  • Static class members
  • Abstract classes and interfaces
  • Inheritance and polymorphism

By mastering access modifiers and other object-oriented programming concepts, you'll be well-equipped to write clean, maintainable, and secure Typescript code.