TypeScript supports all core principles of object-oriented programming (OOP), including encapsulation, inheritance, and polymorphism. Below, I will provide a detailed explanation of how TypeScript implements these principles with examples.
1. Encapsulation
Encapsulation is a fundamental concept in object-oriented programming, involving the combination of an object's data (properties) and behavior (methods) while restricting direct access to the data. In TypeScript, we implement encapsulation using classes. TypeScript provides three access modifiers—public, private, and protected—to control member accessibility.
Example:
typescriptclass Employee { private name: string; constructor(name: string) { this.name = name; } public getName(): string { return this.name; } } let emp = new Employee("John"); console.log(emp.getName()); // Correct usage // console.log(emp.name); // Error: 'name' is private.
In this example, the name property is declared private, meaning it cannot be accessed directly outside the class but can be accessed indirectly through the getName method, thereby achieving encapsulation.
2. Inheritance
Inheritance enables new classes to inherit properties and methods from existing classes, improving code reusability and establishing a class hierarchy.
Example:
typescriptclass Person { constructor(public name: string) {} walk() { console.log(this.name + " is walking."); } } class Employee extends Person { constructor(name: string, public position: string) { super(name); } work() { console.log(this.name + " is working as a " + this.position); } } let emp = new Employee("John", "Developer"); emp.walk(); // Inherited from Person class emp.work(); // Method of Employee class
Here, the Employee class inherits from Person and adds new properties and methods. Objects of the Employee class can utilize methods from the Person class, such as walk().
3. Polymorphism
Polymorphism is a key concept in object-oriented programming that allows defining operations on different data types using a consistent interface. In TypeScript, we implement polymorphism using interfaces and abstract classes.
Example:
typescriptabstract class Animal { abstract makeSound(): void; } class Dog extends Animal { makeSound() { console.log("Woof Woof"); } } class Cat extends Animal { makeSound() { console.log("Meow"); } } function playWithAnimal(animal: Animal) { animal.makeSound(); } let dog = new Dog(); let cat = new Cat(); playWithAnimal(dog); // Output: Woof Woof playWithAnimal(cat); // Output: Meow
In this example, Animal is an abstract class defining an abstract method makeSound(). The Dog and Cat classes inherit from Animal and provide concrete implementations of makeSound(). This demonstrates polymorphism, where makeSound() is called through an Animal-typed reference, and the specific method invoked depends on the object's actual type.
In summary, TypeScript, as a superset of JavaScript, supports all JavaScript features while adding a robust type system and comprehensive object-oriented programming capabilities. This makes TypeScript an excellent choice for developing large-scale applications.