There are various practical applications for abstract
classes within Angular, with one of the main uses being abstract classes utilized as dependency injection tokens
Dependency Injection Token (implements)
export abstract class AbstractEventService {
dispatchEvent(event: any): void;
listen(event: any): Observable<any>;
}
// Implementing the abstract class as interfaces
export class EventService implements AbstractEventService {
// The compiler will enforce the implementation of dispatchEvent() and listen()
}
// Using the abstract class as a DI token (which cannot be done with interfaces)
providers: [provide: AbstractEventService , useClass: EventService ]
This method is especially beneficial for unit testing. You can override in TestBed.configureTestingModule()
or TestBed.overrideProvider()
Service Base Classes (extends)
While this approach may not be as commonly seen in tutorials or demonstrations, it is prevalent in real-world applications
export abstract class AbstractBaseService {
// Extending classes must implement these properties/functions
protected abstract serviceID: string;
protected abstract provideInitialState(): IState;
protected formatResponse(response: IAccountResponse): IFormattedResponse {
// Logic accessible to subclasses
// Override if necessary
}
}
export class AccountService extends AbstractBaseService {
// Implementing abstract properties and functions
// Override protected/private properties and functions as needed
}
Notes
You'll notice that I discuss overriding protected/private properties and functions - TypeScript has limitations in this aspect, allowing the overriding of all Abstract class properties and functions