Welcome back! Previously, you explored polymorphism and how it empowers you to create flexible code structures using inheritance. In this session, we will take a step further into a crucial aspect of object-oriented programming: Abstraction.
TypeScript provides native support for abstraction through the use of the abstract keyword. Abstract classes in TypeScript allow you to define base classes that cannot be instantiated directly. These classes can include abstract methods — methods without an implementation — which must be implemented by any derived (sub) class. This enforces a contract for subclasses, ensuring that certain methods are always present and implemented.
By leveraging abstract classes and methods, you can create clear and maintainable code structures, encouraging consistency and reusability across your codebase.
In TypeScript, you can declare an abstract class using the abstract keyword. Abstract methods are also marked with abstract and do not include an implementation in the base class. Here’s how you can define an abstract class with abstract methods:
In this example, the Shape class is abstract and cannot be instantiated directly. The area and perimeter methods are declared as abstract, meaning any subclass of Shape must provide its own implementations. The getColor method is a concrete method that can be used by all subclasses.
Let’s create concrete classes that extend the abstract Shape class. Each subclass must implement the abstract methods defined in the base class.
Circle Class
The Circle class extends Shape and provides concrete implementations for the area and perimeter methods. The constructor initializes the circle’s radius and color, passing the color to the base class constructor using super.
Similarly, the Rectangle class extends Shape, implementing the required area and perimeter methods and initializing its own attributes through the constructor.
Let’s see how you can utilize these classes in TypeScript, taking advantage of type safety and abstraction:
By running this code, you can see how the Circle and Rectangle classes implement the required methods from the abstract base class. TypeScript’s type system ensures that you cannot instantiate the abstract class directly and that all abstract methods are implemented in derived classes.
-
Abstract Classes
- Can include both method implementations and abstract methods.
- Can have fields, constructors, and visibility modifiers.
- Use when you want to share code or state among related classes.
-
Interfaces
- Only define method and property signatures—no implementation or state.
- Use when you want to define a contract for any class to implement, regardless of its place in the hierarchy.
Summary:
Use an abstract class for shared code and enforced structure among related classes. Use an interface to define a contract that can be implemented by any class.
Example:
Abstraction in TypeScript allows you to define clear contracts for your code, ensuring that all derived classes implement essential functionality. This leads to:
- More organized and readable code: Abstract classes and methods enforce consistent structures and behaviors.
- Greater code reusability: Shared functionality can be placed in base classes, reducing duplication.
- Enhanced flexibility and maintainability: You can extend and modify your codebase with confidence, knowing that essential methods are always present in subclasses.
By mastering abstraction in TypeScript, you are building a strong foundation for creating robust, scalable, and maintainable software systems.
Intrigued? Let's move on to the practice section and solidify these concepts together. You're on your way to becoming proficient in building sophisticated and maintainable systems with TypeScript!
