Access Modifiers
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:
-
public
: Class members declared aspublic
are accessible from anywhere, both within and outside the class. This is the default access modifier if none is specified. -
private
: Class members declared asprivate
are only accessible within the class itself. They cannot be accessed or modified from outside the class, even by subclasses. -
protected
: Class members declared asprotected
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:
-
Declare class properties with the appropriate access modifier (
public
,private
, orprotected
) before the property name. -
Declare class methods with the appropriate access modifier before the method name.
-
Access
public
members directly using dot notation, such asperson.name
orperson.greet()
. -
Access
private
members only within the class itself. Attempting to access them outside the class will result in a compile-time error. -
Access
protected
members within the class and its subclasses. Subclasses can access and modifyprotected
members using thethis
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
orprotected
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.