Exploring Object-Oriented Programming Relationships with TypeScript

Karim Adel
Aug 30, 2023
3 min read
post_comment9 Comments
post_like6 Likes

#Exploring Object-Oriented Programming Relationships with TypeScript

Object-Oriented Programming (OOP) has long been celebrated for its ability to enhance code organization, reusability, and maintainability through the use of classes and their relationships. In OOP, various types of relationships can be established between classes, including inheritance, association, composition, and aggregation. These relationships are vital for creating robust and flexible software systems. In this article, we'll delve into each of these relationships and provide TypeScript examples to illustrate them.

#Inheritance: "IS-A" Relationship

Inheritance is a fundamental concept in OOP that represents an "IS-A" relationship between classes. In other words, it allows a new class to inherit properties and behaviors from an existing class. This relationship facilitates code reuse and the creation of specialized classes.

Consider the real-world scenario of a college. In this scenario, we can define a base classStaffMember, which represents the common attributes and methods of all staff members. Then, we can create subclasses such asHOD(Head of Department) andTeacher, which inherit from theStaffMemberclass.

class StaffMember {
    idCard: string;
    constructor(idCard: string) {
        this.idCard = idCard;
    }
}

class HOD extends StaffMember {
    staff: StaffMember[];
    constructor(idCard: string) {
        super(idCard);
        this.staff = [];
    }
}

class Teacher extends StaffMember {
    // Additional properties and methods specific to teachers
}

In this example, theHODandTeacherclasses are derived from theStaffMemberclass using inheritance. They inherit theidCardproperty and its initialization logic. This modeling accurately represents the "IS-A" relationship between staff members, heads of departments, and teachers.

#Composition: "Part-of" Relationship

Composition represents a "part-of" relationship between classes. It involves using instance variables that reference other objects, allowing one class to be composed of or contain instances of other classes. In this relationship, the involved entities are tightly connected and cannot exist independently.

Let's explore the classic example of a car and its engine. The engine is a crucial part of a car, and the two are interdependent.

class Engine {
    // Engine properties and methods
}

class Car {
    engine: Engine;
    constructor(engine: Engine) {
        this.engine = engine;
    }
}

In this example, theCarclass is composed of an instance of theEngineclass. Theengineinstance variable represents the "part-of" relationship between a car and its engine. Without an engine, a car cannot function properly. This close relationship exemplifies composition.

#Association: Interdependent Relationship

Association signifies a relationship between classes where they interact with each other. Both entities in an association have their own lifecycle, and they can use each other's objects for specific functionalities.

Imagine an example where there areEmployeeandManagerclasses, both of which interact with each other.

class Employee {
    manager: Manager | null;
    constructor() {
        this.manager = null;
    }
    // Other employee-specific properties and methods
}

class Manager {
    employees: Employee[];
    constructor() {
        this.employees = [];
    }
    // Other manager-specific properties and methods
}

// Establishing the association
const employee = new Employee();
const manager = new Manager();

employee.manager = manager;
manager.employees.push(employee);

In this example, theEmployeeandManagerclasses are associated with each other. AnEmployeecan have a reference to aManager, and aManagercan keep track of their employees. This bi-directional interaction demonstrates the association relationship, and we get more details about this concept in independet article.

#Aggregation: "Has-A" Relationship

Aggregation represents a "has-a" relationship between classes. It's a specialized form of association where one entity acts as the owner while the other entities work together for a specific purpose. The relationship is typically one-way, and the aggregated entity can exist independently.

Consider the example of aStudentclass and anAddressclass. Each student must have an address, but an address can exist without being associated with a student.

class Address {
    // Address properties
}

class Student {
    address: Address;
    constructor(address: Address) {
        this.address = address;
    }
}

In this example, theStudentclass has an "aggregation" relationship with theAddressclass. EachStudent"has-a" reference to anAddress, indicating ownership. However, anAddresscan exist independently without being tied to a student.

You are not logged in.