Advanced OOP
🏛️ Advanced OOP
🔷 Abstract Classes: Enforce Contracts
An abstract class can't be instantiated. It defines a contract that subclasses must implement:
Abstract Methods
abstract methodName(); — no body. Subclasses must implement.
Abstract Properties
abstract prop: Type; — subclasses must define.
Concrete Methods
Regular methods with bodies. Subclasses can override or use as-is.
Use Case
Define a template. Subclasses fill in the details.
🔒 Access Modifiers: Control Visibility
TypeScript provides public, private, and protected to control who can access members:
Access Levels
public (default)
private
protected
readonly
📌 Static Members: Class-Level Data
Static members belong to the class itself, not instances:
Static Properties
static prop: Type; — shared by all instances.
Static Methods
static methodName() { } — called on the class, not instances.
Access
Use ClassName.property, not instance.property.
Use Cases
Configuration, factories, utility functions, singletons.
🎯 Getters & Setters: Computed Properties
Getters and setters let you use properties while running custom logic:
Why use getters/setters?
- Validation: Check constraints before setting
- Computed values: Calculate on-the-fly
- Side effects: Log, notify, update cache
- Clean API: Property syntax instead of methods
🏗️ Real-World Pattern: Sealed Class with Private State
Robust Configuration Class
💻 Coding Challenges
Challenge 1: Abstract Class with Multiple Subclasses
Create an abstract Vehicle class with abstract methods. Implement two subclasses (Car, Bike) that satisfy the contract.
Goal: Practice abstract classes and polymorphism.
Challenge 2: Access Control & Encapsulation
Create a BankAccount class with private balance, public deposit/withdraw methods, and a getter for balance. Ensure balance can't go negative.
Goal: Understand private/public boundaries and encapsulation.
Challenge 3: Static Singleton Pattern
Create a Database class with a static getInstance() method that returns a single instance (singleton). Add static initialization logic.
Goal: Implement the singleton pattern with static members.
TypeScript's private is compile-time only. In the compiled JavaScript, private fields are just regular properties—they're not truly inaccessible at runtime. For true privacy, use JavaScript's # private fields. But for most purposes, TypeScript's private is sufficient discipline.
🎯 What's Next
With advanced OOP patterns mastered, we'll explore Type Utilities & Inference — leveraging TypeScript's powerful type system to build reusable, composable type utilities.