In TypeScript, method overriding allows derived classes to provide a specific implementation for a method that is already defined in a base class. Similar to other object-oriented programming languages, such as Java, method overriding enables the polymorphism i.e. different objects of the same type can exhibit different behaviors based on their specific class implementations.
1. Method Overriding Rules
In TypeScript, method overriding is achieved when the method in the derived class has the following:
- the same name and compatible signature (parameter types and return type)
- access modifier that is less restrictive than the base method
In the following example, we have a create() in the Service class. Let us see how to override this method in DerivedService class correctly.
class Service {
public create(resource: Resource): Status {
// Implementation
}
}
class DerivedService extends Service {
public create(resource: Resource): Status {
// Override implementation
}
}
For reference, let’s see what are not the valid method override examples:
- In the first example, the parameter type changed from Resource to string.
- In the second example, the return type changed from Status to string.
- In the third example, the access modifier became more restrictive from public to private.
- In the fourth example, an additional parameter was added.
//1
public create(resourceId: string): Status { ... } //Incorrect override: Parameter type is changed
//2
public create(resource: Resource): string { ... } //Incorrect override: Return type is changed
//3
private create(resource: Resource): Status { ... } //Incorrect override: More restrictive access modifier
//4
public create(status: Status, resource: Resource): Status { ... } // Incorrect override: Parameters changed
2. The ‘override’ Keyword
This is a good practice to add the override keyword in the overriding method in the derived class. This way, TypeScript can check the syntax and catch potential errors at compile time. Almost all IDEs support this type of keywords, so we can identify the mistakes immediately when we override a method.
The ‘override’ keyword will assert that the function it describes is present in the parent class.
In this example, the ‘override’ keyword indicates that create() method in the DerivedService class overrides the create() method in the Service class.
class Service {
public create(resource: Resource): Status {
// ...
}
}
class DerivedService extends Service {
public override create(resource: Resource): Status {
// ...
}
}
If we want to make the use of ‘override‘ keyword mandatory, we can enable the ‘noImplicitOverride‘ options in the tsconfig.json.
{
"compilerOptions": {
// ...
"noImplicitOverride": true
}
}
3. Accessing Members of Base Class
TypeScript provides the ‘super‘ keyword that we can use in derived classes, including the overriding methods, to access the properties and methods of the base class.
We can use ‘super’ keyword to avoid any name conflict in cases such as this.
class Service {
public create(resource: Resource): Status {
// ...
}
}
class DerivedService extends Service {
@override
public create(resource: Resource): Status {
Status status = super.create(resource);
// Additional logic
}
}
4. Conclusion
In this TypeScript tutorial, we explored the fundamental concepts of method override. We discussed the method overriding rules, variations, and examples. As a best practice, it is recommended to use the ‘override’ keyword in the method in the derived class so rule out any mistake as early as possible.
Happy Learning !!
Comments