Object-Oriented Programming (OOP):
OOP is a programming paradigm that uses objects and classes to organize and structure code. It encourages the use of objects as self-contained units with properties and methods.Example:
class Person {
constructor(private name: string) {}
sayHello() {
console.log(`Hello, my name is ${this.name}.`);
}
}
const user = new Person('Alice');
user.sayHello(); // Output: Hello, my name is Alice.
Working With Classes:
Classes in TypeScript provide a blueprint for creating objects. They encapsulate properties and methods related to a particular entity.Example:
class Rectangle {
constructor(private width: number, private height: number) {}
calculateArea() {
return this.width * this.height;
}
}
const rect = new Rectangle(5, 10);
console.log(`Area: ${rect.calculateArea()}`); // Output: Area: 50
Constructors:
Constructors are special methods within classes that are called when an object of the class is created. They initialize object properties.Example:
class Dog {
constructor(private name: string) {}
bark() {
console.log(`${this.name} says woof!`);
}
}
const myDog = new Dog('Buddy');
myDog.bark(); // Output: Buddy says woof!
Access Modifiers:
Access modifiers like public, private, and protected control the visibility of class members. They determine whether a member can be accessed outside the class.Example:
class BankAccount {
private balance: number = 0;
constructor(private accountNumber: string) {}
deposit(amount: number) {
this.balance += amount;
}
getBalance() {
return this.balance;
}
}
Readonly Modifiers:
The readonly modifier allows you to create properties that can only be assigned a value once, typically in the constructor.Example:
class Circle {
constructor(readonly radius: number) {}
}
const myCircle = new Circle(5);
console.log(`Radius: ${myCircle.radius}`); // Output: Radius: 5
Members and Accessors:
Members are properties and methods of a class. Accessors, like getters and setters, control access to class properties.Example:
class Temperature {
private _celsius: number = 0;
get celsius() {
return this._celsius;
}
set celsius(value: number) {
this._celsius = value;
}
}
Instance Members:
Instance members belong to individual objects created from a class.Example:
class Counter {
private count: number = 0;
increment() {
this.count++;
}
getCount() {
return this.count;
}
}
const counter1 = new Counter();
const counter2 = new Counter();
counter1.increment();
console.log(`Counter 1: ${counter1.getCount()}`); // Output: Counter 1: 1
console.log(`Counter 2: ${counter2.getCount()}`); // Output: Counter 2: 0
Static Members:
Static members belong to the class itself, not to instances of the class.Example:
class MathHelper {
static PI: number = 3.14159;
static calculateCircleArea(radius: number) {
return MathHelper.PI * radius * radius;
}
}
console.log(`Area of a circle with radius 2: ${MathHelper.calculateCircleArea(2)}`); // Output: Area of a circle with radius 2: 12.56636
Accessors:
Accessors, like getters and setters, allow controlled access to class properties.Example:
class Person {
private _age: number = 0;
get age() {
return this._age;
}
set age(value: number) {
if (value >= 0 && value <= 120) {
this._age = value;
} else {
console.error('Invalid age');
}
}
}
Inheritance:
Inheritance allows a class to inherit properties and methods from another class. It promotes code reuse and hierarchy.Example:
class Animal {
constructor(private name: string) {}
makeSound() {
console.log(`${this.name} makes a sound.`);
}
}
class Dog extends Animal {
constructor(name: string, private breed: string) {
super(name);
}
makeSound() {
console.log(`${this.name} barks.`);
}
}
const myDog = new Dog('Buddy', 'Golden Retriever');
myDog.makeSound(); // Output: Buddy barks.
Polymorphism:
Polymorphism allows objects of different classes to be treated as instances of a common superclass. It enables flexibility and extensibility in code.Example:
class Shape {
area() {
return 0;
}
}
class Circle extends Shape {
constructor(private radius: number) {
super();
}
area() {
return Math.PI * this.radius * this.radius;
}
}
class Square extends Shape {
constructor(private sideLength: number) {
super();
}
area() {
return this.sideLength * this.sideLength;
}
}
const shapes: Shape[] = [new Circle(5), new Square(4)];
shapes.forEach((shape) => console.log(`Area: ${shape.area()}`));
Method Overloading:
Method overloading allows a class to have multiple methods with the same name but different parameter types or numbers of parameters.Example:
class Calculator {
add(a: number, b: number): number;
add(a: string, b: string): string;
add(a: any, b: any): any {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
} else if (typeof a === 'string' && typeof b === 'string') {
return a + b;
}
return null;
}
}
const calc = new Calculator();
console.log(calc.add(2, 3)); // Output: 5
console.log(calc.add('Hello', ' TypeScript')); // Output: Hello TypeScript
Abstract Class and Interface:
Abstract classes and interfaces define contracts for classes to follow. Abstract classes can have both concrete and abstract methods, while interfaces only define method signatures.Example:
abstract class Shape {
abstract calculateArea(): number;
}
class Circle extends Shape {
constructor(private radius: number) {
super();
}
calculateArea() {
return Math.PI * this.radius * this.radius;
}
}
interface Printable {
printDetails(): void;
}
class Square implements Printable {
constructor(private sideLength: number) {}
printDetails() {
console.log(`Square with side length ${this.sideLength}`);
}
}
Interface Usage and Inheritance:
Interfaces can be used to define contracts that classes must implement. They can also be extended by other interfaces to build more specific contracts.Example:
interface Vehicle {
start(): void;
stop(): void;
}
interface ElectricVehicle extends Vehicle {
charge(): void;
}
class Car implements ElectricVehicle {
start() {
console.log('Car started');
}
stop() {
console.log('Car stopped');
}
charge() {
console.log('Charging car');
}
}
Interface Extending Class:
Interfaces can extend classes to capture the shape of class instances, including their properties and methods.Example:
class Person {
constructor(public name: string) {}
sayHello() {
console.log(`Hello, my name is ${this.name}.`);
}
}
interface Greetable extends Person {
greet(): void;
}
const user: Greetable = new Person('Alice');
user.sayHello(); // Output: Hello, my name is Alice.
user.greet(); // This is allowed due to the interface extending the class.