Abstraction and Polymorphism

Abstraction with Interfaces#

Abstraction is the process of designing a class so that its public properties and methods reveal as little as possible about the inner workings of the class. In the Encapsulation section, we mentioned that information hiding uses high-level methods to hide the details of the underlying data in the class. Information hiding is therefore a form of abstraction.

Abstraction can be explicitly implemented in TypeScript using interfaces, which allow us to declare the public properties and methods that should be implemented by one or more classes. Continuing the Product example from the previous section, we create a Display interface to represent the behavior of printing a display name:

We use the implements keyword to ensure that the Product class implements the printDisplay() method specified in the Display interface.

Using the Display interface, we can write code that depends on that interface as opposed to a concrete class. For example, we can write a printMultiple() function that prints an array of Display objects:

Notice that the printMultiple() function has no idea that we are passing in an array of Product objects. We can pass in any class that implements the Display interface. The ability to use a more specific type (Product) in place of a more general type (Display) is known as polymorphism.

Using Polymorphism#

In Greek, "Poly" means "many" while "morph" means "shape". Put them together and you get "many shapes".

In OOP, polymorphism is an object's ability to represent many shapes. In our Product example above, a Product object can represent two shapes: a Product and a Display.