In this section, we will delve into one of the core features of TypeScript: Classes. Classes are a blueprint for creating objects with predefined properties and methods. They are a fundamental part of object-oriented programming (OOP) and are used extensively in TypeScript to create reusable and maintainable code.

Key Concepts

  1. Class Definition: How to define a class in TypeScript.
  2. Constructors: Special methods for initializing new objects.
  3. Properties: Variables that belong to the class.
  4. Methods: Functions that belong to the class.
  5. Access Modifiers: Keywords that set the accessibility of properties and methods.
  6. Inheritance: Mechanism to create a new class from an existing class.
  7. Abstract Classes: Classes that cannot be instantiated and are meant to be subclassed.

Class Definition

A class in TypeScript is defined using the class keyword followed by the class name. Here's a simple example:

class Person {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    greet() {
        console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
    }
}

const person1 = new Person("Alice", 30);
person1.greet(); // Output: Hello, my name is Alice and I am 30 years old.

Explanation

  • Class Definition: class Person { ... } defines a new class named Person.
  • Properties: name and age are properties of the class.
  • Constructor: constructor(name: string, age: number) { ... } is a special method that initializes the properties.
  • Methods: greet() is a method that belongs to the class.

Access Modifiers

TypeScript provides three access modifiers to control the visibility of class members:

  1. public: Accessible from anywhere.
  2. private: Accessible only within the class.
  3. protected: Accessible within the class and its subclasses.
class Employee {
    public name: string;
    private salary: number;
    protected department: string;

    constructor(name: string, salary: number, department: string) {
        this.name = name;
        this.salary = salary;
        this.department = department;
    }

    public getDetails() {
        return `Name: ${this.name}, Department: ${this.department}`;
    }

    private getSalary() {
        return this.salary;
    }
}

const emp = new Employee("Bob", 50000, "Engineering");
console.log(emp.getDetails()); // Output: Name: Bob, Department: Engineering
// console.log(emp.getSalary()); // Error: Property 'getSalary' is private and only accessible within class 'Employee'.

Explanation

  • public: name and getDetails() are accessible from outside the class.
  • private: salary and getSalary() are only accessible within the class.
  • protected: department is accessible within the class and its subclasses.

Inheritance

Inheritance allows a class to inherit properties and methods from another class. The class that is inherited from is called the parent or base class, and the class that inherits is called the child or derived class.

class Animal {
    name: string;

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

    move(distance: number) {
        console.log(`${this.name} moved ${distance} meters.`);
    }
}

class Dog extends Animal {
    bark() {
        console.log("Woof! Woof!");
    }
}

const dog = new Dog("Buddy");
dog.bark(); // Output: Woof! Woof!
dog.move(10); // Output: Buddy moved 10 meters.

Explanation

  • Base Class: Animal is the base class with a property name and a method move().
  • Derived Class: Dog extends Animal and inherits its properties and methods. It also has an additional method bark().

Abstract Classes

Abstract classes are classes that cannot be instantiated directly. They are meant to be subclassed and can contain abstract methods that must be implemented by derived classes.

abstract class Shape {
    abstract area(): number;

    displayArea() {
        console.log(`Area: ${this.area()}`);
    }
}

class Circle extends Shape {
    radius: number;

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

    area(): number {
        return Math.PI * this.radius * this.radius;
    }
}

const circle = new Circle(5);
circle.displayArea(); // Output: Area: 78.53981633974483

Explanation

  • Abstract Class: Shape is an abstract class with an abstract method area().
  • Derived Class: Circle extends Shape and provides an implementation for the area() method.

Practical Exercises

Exercise 1: Create a Class

Create a class Car with properties make, model, and year. Add a method getDetails() that returns a string with the car's details.

class Car {
    make: string;
    model: string;
    year: number;

    constructor(make: string, model: string, year: number) {
        this.make = make;
        this.model = model;
        this.year = year;
    }

    getDetails() {
        return `${this.year} ${this.make} ${this.model}`;
    }
}

const car = new Car("Toyota", "Corolla", 2020);
console.log(car.getDetails()); // Output: 2020 Toyota Corolla

Exercise 2: Implement Inheritance

Create a base class Person with properties name and age, and a method introduce(). Create a derived class Student that adds a property grade and overrides the introduce() method to include the grade.

class Person {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    introduce() {
        return `Hi, I'm ${this.name} and I'm ${this.age} years old.`;
    }
}

class Student extends Person {
    grade: string;

    constructor(name: string, age: number, grade: string) {
        super(name, age);
        this.grade = grade;
    }

    introduce() {
        return `${super.introduce()} I'm in grade ${this.grade}.`;
    }
}

const student = new Student("John", 16, "10th");
console.log(student.introduce()); // Output: Hi, I'm John and I'm 16 years old. I'm in grade 10th.

Summary

In this section, we covered the basics of classes in TypeScript, including class definition, constructors, properties, methods, access modifiers, inheritance, and abstract classes. We also provided practical exercises to reinforce the concepts. Understanding these fundamentals will help you create more structured and maintainable code in TypeScript. In the next section, we will explore Enums and their usage in TypeScript.

© Copyright 2024. All rights reserved