Activity 11: Object-Oriented Programming OOP in TypeScript

Class and Object

Definition: Classes are blueprints for creating objects. They define properties and methods that the created objects will have.

Key Features:

  • Classes: Act as templates.

  • Objects: Instances of classes.

How it’s Implemented in TypeScript: Define a class with properties and methods, then create objects using the new keyword.

Example Code:

class Ballpen {
  brand: string;
  color: string;

  constructor(brand: string, color: string) {
    this.brand = brand;
    this.color = color;
  }

  write(): string {
    return `Writing with a ${this.color} ${this.brand} ballpen.`;
  }
}

const ballpen1 = new Ballpen("Parker", "blue");
console.log(ballpen1.write()); // Writing with a blue Parker ballpen.

Encapsulation

Definition: Encapsulation hides the internal details of a class and exposes only what is necessary.

Key Features:

  • Access Modifiers: Control access to class properties and methods (public, private, protected).

How it’s Implemented in TypeScript: Use access modifiers to control the visibility of class members.

Example Code:

class Mug {
  private capacity: number; // in milliliters
  public color: string;

  constructor(capacity: number, color: string) {
    this.capacity = capacity;
    this.color = color;
  }

  public getCapacity(): number {
    return this.capacity;
  }
}

const mug1 = new Mug(300, "red");
console.log(mug1.color); // red
console.log(mug1.getCapacity()); // 300

Inheritance

Definition: Inheritance allows one class to inherit properties and methods from another class.

Key Features:

  • Extends: Used to inherit from a base class.

  • Overriding Methods: Subclasses can override methods of the base class.

How it’s Implemented in TypeScript: Use the extends keyword to create a subclass.

Example Code:

class Device {
  protected model: string;

  constructor(model: string) {
    this.model = model;
  }

  info(): string {
    return `Device model: ${this.model}`;
  }
}

class Charger extends Device {
  private voltage: number;

  constructor(model: string, voltage: number) {
    super(model);
    this.voltage = voltage;
  }

  info(): string {
    return `${super.info()} with voltage: ${this.voltage}V`;
  }
}

const charger1 = new Charger("Samsung Fast Charger", 9);
console.log(charger1.info()); // Device model: Samsung Fast Charger with voltage: 9V

Polymorphism

Definition: Polymorphism allows different classes to be treated as instances of the same class through a common interface or base class.

Key Features:

  • Method Overriding: Runtime polymorphism where a subclass provides a specific implementation of a method already defined in its base class.

  • Method Overloading: Compile-time polymorphism where multiple methods have the same name but different parameters.

How it’s Implemented in TypeScript: Implement method overriding and overloading in TypeScript.

Example Code:

class Item {
  describe(): string {
    return "This is an item.";
  }
}

class Ballpen extends Item {
  describe(): string {
    return "This is a ballpen.";
  }
}

class Mug extends Item {
  describe(): string {
    return "This is a mug.";
  }
}

function printDescription(item: Item): void {
  console.log(item.describe());
}

const ballpen1 = new Ballpen();
const mug1 = new Mug();

printDescription(ballpen1); // This is a ballpen.
printDescription(mug1); // This is a mug.

Abstraction

Definition: Abstraction hides complex implementation details and shows only the essential features of an object.

Key Features:

  • Abstract Classes: Cannot be instantiated directly and can contain abstract methods.

  • Interfaces: Define a contract for classes to implement.

How it’s Implemented in TypeScript: Use abstract classes and interfaces to achieve abstraction.

Example Code:

abstract class Appliance {
  abstract operate(): string;
}

class MugWarmer extends Appliance {
  operate(): string {
    return "Mug warmer is now on.";
  }
}

const mugWarmer = new MugWarmer();
console.log(mugWarmer.operate()); // Mug warmer is now on.

Interfaces

Definition: Interfaces define the structure of an object, including the types of properties and methods.

Key Features:

  • Structural Contracts: Define how objects should be shaped.

How it’s Implemented in TypeScript: Use interfaces to define the shape of objects and enforce a contract.

Example Code:

interface Product {
  name: string;
  price: number;
  getDetails(): string;
}

class Charger implements Product {
  constructor(public name: string, public price: number) {}

  getDetails(): string {
    return `Charger: ${this.name}, Price: $${this.price}`;
  }
}

const charger1 = new Charger("Apple Charger", 19.99);
console.log(charger1.getDetails()); // Charger: Apple Charger, Price: $19.99

Constructor Overloading

Definition: Constructor overloading allows multiple constructor definitions in a class.

Key Features:

  • Optional Parameters: Provide flexibility in object creation.

How it’s Implemented in TypeScript: Use optional parameters to simulate constructor overloading.

Example Code:

class Ballpen {
  brand: string;
  color?: string;

  constructor(brand: string, color?: string) {
    this.brand = brand;
    this.color = color;
  }

  getDetails(): string {
    return this.color ? `${this.brand} ballpen in ${this.color}` : `${this.brand} ballpen`;
  }
}

const ballpen1 = new Ballpen("Parker");
const ballpen2 = new Ballpen("Parker", "black");

console.log(ballpen1.getDetails()); // Parker ballpen
console.log(ballpen2.getDetails()); // Parker ballpen in black

Getters and Setters

Definition: Getters and setters provide controlled access to class properties.

Key Features:

  • Encapsulation: Control how properties are accessed and modified.

How it’s Implemented in TypeScript: Use get and set methods for encapsulation.

Example Code:

class Mug {
  private _capacity: number;

  constructor(capacity: number) {
    this._capacity = capacity;
  }

  get capacity(): number {
    return this._capacity;
  }

  set capacity(value: number) {
    if (value > 0) this._capacity = value;
  }
}

const mug1 = new Mug(300);
console.log(mug1.capacity); // 300
mug1.capacity = 400;
console.log(mug1.capacity); // 400

References

https://dev.to/mohammadbahmani/mastering-object-oriented-programming-in-typescript-your-complete-guide-with-practical-examples-476h

https://dev.to/kevin_odongo35/object-oriented-programming-with-typescript-574o

https://betterprogramming.pub/understand-object-oriented-programming-with-typescript-c4ff8afa40d