TypeScript Abstract Class

A TypeScript Abstract class is a class which may have some unimplemented methods. These methods are called abstract methods. We can't create an instance of an abstract class. But other classes can derived from abstract class and reuse the functionality of base class.

TypeScript Interface vs Abstract Class

Interface Abstract Class
All members are abstract. Some members are abstract and some are fully implemented.
Interfaces support multiple inheritances. Abstract class does not support multiple inheritances.
TypeScript Interface has zero JavaScript code that means it is only available in TypeScript and does not produce any code in compiled JavaScript file. Abstract class compile to JavaScript functions.
Interfaces are generic in nature. They can be implemented by any class for example IClone interface can be implemented by any class like business objects, database classes. Abstract classes are related. For example ViewModelBase is an abstract, class then we know this class will only inherits by ViewModels.

Syntax

abstract class BaseEmployee {
    abstract doWork(): void;

    workStarted(): void {
        console.log('work started.');
    }
}

In above example, we have created an abstract class. First method doWork is abstract and we put abstract keyword before the method name. Abstract method does not have any implementation. Second method workStarted has implementation and it is not an abstract method.

Constructor

In abstract class, we can write constructor which automatically executes when user creates a new instance of derived class. Constructor function always has same name constructor and it may have parameters. Below is the constructor example:

abstract class BaseEmployee {
    firstName: string;
    lastName: string;

    constructor(firstName: string, lastName: string) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

Constructor is always used to initialize variables values and object setup work. In above, we have a constructor of BaseEmployee which takes two parameters firstName and lastName. In constructor, we have assigned parameter values to our variables.

Derived Cass

abstract class BaseEmployee {
    firstName: string;
    lastName: string;

    constructor(firstName: string, lastName: string) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    abstract doWork(): void;
}

class Employee extends BaseEmployee {
    constructor(firstName: string, lastName: string) {
        super(firstName, lastName);
    }

    doWork(): void {
        console.log(`${this.lastName}, ${this.firstName} doing work...`);
    }
}

let emp = new Employee('Dana', 'Ryan');
emp.doWork(); //Print Ryan, Dana doing work...

In above example, we have created an abstract class BaseEmployee. We have one abstract method doWork which we do not provide any implementation. Employee class extends BaseEmployee class. In Employee class constructor we call BaseEmployee constructor using super method. super method is used to call base class constructor. super method takes the same parameters as defined in base class constructor.

In last two lines, we have created an instance of Employee class and call doWork method.

Implement Interface

An abstract class can implement one or more interface. You can learn more about interfaces here. Below is the example of implementing interface by abstract class.

interface IName {
    firstName: string
    lastName: string;
}

interface IWork {
    doWork(): void;
}

abstract class BaseEmployee implements IName, IWork {
    firstName: string;
    lastName: string;

    constructor(firstName: string, lastName: string) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    abstract doWork(): void;
}

class Employee extends BaseEmployee {
    constructor(firstName: string, lastName: string) {
        super(firstName, lastName);
    }

    doWork(): void {
        console.log(`${this.lastName}, ${this.firstName} doing work...`);
    }
}

let emp: IWork = new Employee('Dana', 'Ryan');
emp.doWork();

In above example, we have created two interfaces IName and IWork. Both interfaces are implemented by BaseEmployee abstract class by using implements keyword in highlighted line 10. Employee class extends BaseEmployee class. In line 32, we have created an emp variable of interface IWork and assign a new instance of Employee class. Now only member available in emp variable is doWork as emp variable data type is interface IWork.

Join our newsletter and get an occasional email with a technology and DotNetPattern.com news update.