TypeScript Abstract Classes
Abstract classes are base classes from which other classes may be derived. They may not be instantiated directly. Unlike an interface, an abstract class may contain implementation details for its members.
1. Defining an Abstract Class
You use the abstract keyword to define an abstract class.
abstract class Animal {
constructor(public name: string) {}
// Concrete method: has implementation
move(): void {
console.log("Roaming the earth...");
}
// Abstract method: must be implemented by derived classes
abstract makeSound(): void;
}
2. Implementing an Abstract Class
You cannot create an instance of Animal directly. You must create a subclass that extends it and implements all abstract methods.
class Dog extends Animal {
constructor(name: string) {
super(name); // Must call super()
}
// Implementation of abstract method
makeSound(): void {
console.log("Woof! Woof!");
}
}
// let a = new Animal("Ghost"); // Error: Cannot create an instance of an abstract class
let d = new Dog("Buddy");
d.makeSound(); // "Woof! Woof!"
d.move(); // "Roaming the earth..."
3. Abstract Classes vs Interfaces
| Feature | Abstract Class | Interface |
|---|---|---|
| Implementation | Can have implementation details (methods with bodies) | No implementation (pure signatures) |
| Access Modifiers | Can use public, protected, private |
Members are implicitly public |
| Inheritance | A class can extend only one abstract class | A class can implement multiple interfaces |
| JavaScript Output | Compiles to a JavaScript class | Disappears completely (zero runtime code) |
4. When to use which?
- Use Abstract Classes when you want to share code (implementation) among several closely related classes.
- Use Interfaces when you want to define a contract (shape) for disparate classes or objects, or when you need multiple inheritance of types.