# Activity 10: Object-Oriented Programming OOP in TypeScript

## 1\. Class and Object

### Definition

* **Class**: A class is a blueprint for creating objects, defining properties and methods that the created objects will have.
    
* **Object**: An object is an instance of a class, representing a specific entity with actual values.
    

### Key Features

* Encapsulates data and behavior.
    
* Supports instantiation, allowing multiple objects to be created from the same class.
    

### How it’s Implemented in TypeScript

You define a class using the `class` keyword, and create an object using the `new` keyword.

### Example Code

```abap
class Car {
  // Properties
  make: string;
  model: string;

  // Constructor
  constructor(make: string, model: string) {
    this.make = make;
    this.model = model;
  }

  // Method
  displayInfo(): void {
    console.log(`Car Make: ${this.make}, Model: ${this.model}`);
  }
}

// Creating an object
const myCar = new Car('Toyota', 'Corolla');
myCar.displayInfo(); // Output: Car Make: Toyota, Model: Corolla
```

## 2\. Encapsulation

### Definition

Encapsulation is the concept of wrapping data (properties) and methods (functions) together in a single unit (class) while restricting access to some components.

### Key Features

* Hides internal state and requires all interaction to be performed through an object's methods.
    
* Enhances security and reduces complexity.
    

### How it’s Implemented in TypeScript

TypeScript uses access modifiers: `public`, `private`, and `protected` to control access.

### Example Code

```abap
class BankAccount {
  private balance: number = 0; // Private property

  deposit(amount: number): void {
    this.balance += amount;
  }

  getBalance(): number {
    return this.balance;
  }
}

const account = new BankAccount();
account.deposit(100);
console.log(account.getBalance()); // Output: 100
// console.log(account.balance); // Error: Property 'balance' is private
```

## 3\. Inheritance

### Definition

Inheritance is the mechanism by which one class can inherit the properties and methods of another class.

### Key Features

* Promotes code reusability.
    
* Allows for the creation of hierarchical class structures.
    

### How it’s Implemented in TypeScript

You use the `extends` keyword to inherit from a parent class.

### Example Code

```abap
class Animal {
  speak(): void {
    console.log('Animal speaks');
  }
}

class Dog extends Animal {
  speak(): void {
    console.log('Dog barks');
  }
}

const dog = new Dog();
dog.speak(); // Output: Dog barks
```

## 4\. Polymorphism

### Definition

Polymorphism allows methods to do different things based on the object it is acting upon, enabling different classes to be treated as instances of the same parent class.

### Key Features

* Supports method overriding (runtime polymorphism).
    
* Supports method overloading (compile-time polymorphism).
    

### How it’s Implemented in TypeScript

Method overriding is done by defining a method in a child class with the same name as in the parent class. TypeScript does not support method overloading in the same way as some other languages, but it can be simulated with optional parameters.

### Example Code

#### Method Overriding

```abap
class Shape {
  area(): number {
    return 0;
  }
}

class Rectangle extends Shape {
  constructor(private width: number, private height: number) {
    super();
  }

  area(): number {
    return this.width * this.height;
  }
}

const rectangle = new Rectangle(10, 5);
console.log(rectangle.area()); // Output: 50
```

#### Method Overloading

```abap
class MathOperations {
  add(a: number, b: number): number;
  add(a: string, b: string): string;
  add(a: any, b: any): any {
    return a + b;
  }
}

const math = new MathOperations();
console.log(math.add(2, 3)); // Output: 5
console.log(math.add('Hello', ' World!')); // Output: Hello World!
```

## 5\. Abstraction

### Definition

Abstraction is the concept of hiding complex realities while exposing only the necessary parts. It helps in reducing programming complexity and effort.

### Key Features

* Provides a simple interface while hiding the implementation details.
    
* Can be implemented using abstract classes and interfaces.
    

### How it’s Implemented in TypeScript

Abstract classes can have abstract methods that must be implemented in derived classes.

### Example Code

```abap
abstract class Animal {
  abstract speak(): void; // Abstract method
}

class Cat extends Animal {
  speak(): void {
    console.log('Cat meows');
  }
}

const cat = new Cat();
cat.speak(); // Output: Cat meows
```

## 6\. Interfaces

### Definition

An interface in TypeScript defines the structure of an object, specifying what properties and methods an object should have without providing implementation.

### Key Features

* Facilitates the implementation of abstraction.
    
* Allows for contract-based programming.
    

### How it’s Implemented in TypeScript

You define an interface using the `interface` keyword.

### Example Code

```abap
interface User {
  name: string;
  age: number;
  greet(): void;
}

class Person implements User {
  constructor(public name: string, public age: number) {}

  greet(): void {
    console.log(`Hello, my name is ${this.name}.`);
  }
}

const user: User = new Person('Alice', 30);
user.greet(); // Output: Hello, my name is Alice.
```

## 7\. Constructor Overloading

### Definition

Constructor overloading allows a class to have multiple constructors with different parameter types or numbers.

### Key Features

* Enables flexibility in object creation.
    

### How it’s Implemented in TypeScript

You can define multiple constructor signatures, but only one implementation.

### Example Code

```abap
class Point {
  constructor(public x: number, public y: number);
  constructor(public x: number);
  constructor(public x: number, public y?: number) {
    this.y = y !== undefined ? y : 0; // Default y to 0
  }
}

const point1 = new Point(5, 10);
const point2 = new Point(5); // y defaults to 0
```

## 8\. Getters and Setters

### Definition

Getters and setters allow you to define how properties of an object are accessed and modified, providing a controlled way to access and update private data.

### Key Features

* Encapsulates property access.
    
* Enables validation or additional logic during property assignment.
    

### How it’s Implemented in TypeScript

You can define getters and setters using the `get` and `set` keywords.

### Example Code

```abap
class Circle {
  private _radius: number;

  constructor(radius: number) {
    this._radius = radius;
  }

  get radius(): number {
    return this._radius;
  }

  set radius(value: number) {
    if (value < 0) {
      throw new Error('Radius cannot be negative');
    }
    this._radius = value;
  }
}

const circle = new Circle(5);
console.log(circle.radius); // Output: 5
circle.radius = 10; // Valid
// circle.radius = -5; // Throws error
```
