Learn how to implement interfaces in TypeScript classes to enforce contracts and promote loose coupling and high cohesion in your code.
In this section, we will explore how to implement interfaces in TypeScript classes. This practice is crucial for ensuring that classes adhere to specific contracts, which enhances code reliability and maintainability. By the end of this section, you’ll understand how to use interfaces to design robust APIs and libraries, promote loose coupling, and achieve high cohesion in your code.
Before diving into implementation, let’s briefly recap what interfaces and classes are:
To implement an interface in a class, we use the implements keyword. This ensures that the class adheres to the structure defined by the interface. Let’s see how this works with a simple example.
Consider an interface Vehicle with properties and methods that any vehicle should have:
interface Vehicle {
make: string;
model: string;
year: number;
start(): void;
stop(): void;
}
class Car implements Vehicle {
make: string;
model: string;
year: number;
constructor(make: string, model: string, year: number) {
this.make = make;
this.model = model;
this.year = year;
}
start(): void {
console.log(`${this.make} ${this.model} started.`);
}
stop(): void {
console.log(`${this.make} ${this.model} stopped.`);
}
}
const myCar = new Car('Toyota', 'Corolla', 2020);
myCar.start(); // Output: Toyota Corolla started.
myCar.stop(); // Output: Toyota Corolla stopped.
In this example, the Car class implements the Vehicle interface. This means the class must provide implementations for all properties and methods defined in the interface.
A class can implement multiple interfaces, allowing it to conform to various contracts. Let’s see how this is done.
Suppose we have two interfaces, Vehicle and Electric, and we want a class to implement both:
interface Electric {
batteryCapacity: number;
charge(): void;
}
class ElectricCar implements Vehicle, Electric {
make: string;
model: string;
year: number;
batteryCapacity: number;
constructor(make: string, model: string, year: number, batteryCapacity: number) {
this.make = make;
this.model = model;
this.year = year;
this.batteryCapacity = batteryCapacity;
}
start(): void {
console.log(`${this.make} ${this.model} started.`);
}
stop(): void {
console.log(`${this.make} ${this.model} stopped.`);
}
charge(): void {
console.log(`${this.make} ${this.model} is charging.`);
}
}
const myElectricCar = new ElectricCar('Tesla', 'Model S', 2021, 100);
myElectricCar.start(); // Output: Tesla Model S started.
myElectricCar.charge(); // Output: Tesla Model S is charging.
Here, ElectricCar implements both Vehicle and Electric interfaces, ensuring it adheres to the contracts of both.
Interfaces play a crucial role in designing APIs and libraries. They define clear contracts for how classes should behave, making it easier for developers to understand and use your code. Here are some benefits:
Loose coupling and high cohesion are two fundamental principles of software design that interfaces help achieve.
Now it’s your turn! Try implementing an interface in a class. Follow these steps:
Animal with properties name and age, and methods speak() and move().Dog that implements the Animal interface.Dog class.Dog class and call its methods.Here’s a starting point:
interface Animal {
name: string;
age: number;
speak(): void;
move(): void;
}
class Dog implements Animal {
// Your code here
}
// Test your implementation
Experiment with the code examples provided. Try modifying the Car or ElectricCar classes to add new features or change existing ones. See how interfaces help maintain the structure and reliability of your code.
To help visualize the relationship between interfaces and classes, let’s use a diagram:
classDiagram
class Vehicle {
+String make
+String model
+int year
+start()
+stop()
}
class Electric {
+int batteryCapacity
+charge()
}
class ElectricCar {
+String make
+String model
+int year
+int batteryCapacity
+start()
+stop()
+charge()
}
Vehicle <|.. ElectricCar
Electric <|.. ElectricCar
Diagram Description: This diagram shows the ElectricCar class implementing both Vehicle and Electric interfaces. The arrows indicate that ElectricCar adheres to the contracts defined by these interfaces.
implements keyword, classes adhere to the structure defined by interfaces.For more information on TypeScript interfaces and classes, check out these resources: