Abstraction, Encapsulation, Inheritance, and Polymorphism - nus-cs2030/2122-s1 GitHub Wiki
Introduction
This page serves as a summary of the four main object oriented principles that we have learned in Lectures 1 to 3, complete with explanations of how these principles can be applied in practice.
Abstraction
Abstraction can be achieved by creating classes that represent objects in the real world. With any object that we may model in the real world, the object has properties/attributes/fields and methods. For example, a Person
object would have attributes of height
and weight
. We can also implement actions that a Person
might perform, for example, a Person
might have a catchBall()
method that models a person catching a ball.
Data Abstraction
By knowing the attributes of a particular object, we have are able to abstract the data of the object. How the attributes of an object is stored or manipulated is irrelevant to the user of the object; the user only needs to know that the object contains those particular attributes.
Functional Abstraction
The user also does not need to understand the implementation of the methods that are called upon an object. The methods defined in an object are free to use any implementation as long as it performs what it is supposed to do.
Encapsulation
Encapsulation hides information from the client so that clients cannot access the attributes of an object. A common way to hide information is through the use of access modifiers, i.e., declaring attributes to be private
. private
attributes can only be accessed within the same class. There is also another reason why attributes should be hidden — since classes are meant to model real-world objects, we should not ask an object for its attributes but rather tell the object what to do (tell-don't-ask) using public or protected methods.
Inheritance
In modelling objects, some objects may be a sub-type of another object. For example, basketball and football are both types of balls. If we want to, say for example, find the volume of the ball, we can implement the method getVolume
in a superclass called Ball
. That way, getVolume
does not have to be implemented separately in Basketball
or Football
, which increases the maintainability of the code by abstracting out the common methods in a super-type. Generally, inheritance is used when a sub-type 'is-a' super-type, e.g., basketball is a ball, instead of when an object 'has-a' other object, e.g., a circle has a point.
Polymorphism
Related to inheritance, polymorphism enables an object to take on many forms. For example, an object declared as a Ball
can be either a Basketball
or a Football
. This ensures that regardless of what type of ball the object is, the object has a getVolume
method defined in the superclass. You could then, for example, get the volume of different types of balls.
Abstract Classes and Interfaces
Abstract classes and interfaces cannot be instantiated and are typically used in the case where the superclass is not something that should be instantiated, e.g., FilledShape
. Because Java forbids multiple inheritance, an object can implement multiple interfaces but can only inherit from one parent class/abstract class.