Understanding the Concept of OOP: Its Four Pillars

Reading Time: 3 minutes

This blog is in the continuation of its first part where we discussed the basic part of object-oriented concepts. In this blog, we will cover four pillars in the object-oriented world of programming in Scala.

OOPS Four Pillars

Four pillars are basically the software design principles that help you to write clean Object-Oriented Code and these are:

  • Abstraction
  • Encapsulation
  • Inheritance
  • Polymorphism

Let’s take a closer look at each of them.

Abstraction in Object Oriented Programming

Abstraction is basically only showing the necessary details to the user of the object. For instance, when you turn on your laptop you just push the power button and the screen of your laptop lit up you don’t care about the inner mechanism of what’s going on and that’s what abstraction is.

The best part of Abstraction is you decouple the user from the underlying implementation. Let’s take a coding example:

Suppose you are making an app that classifies different shapes and calculates their area. So abstraction in your app will be just the area of your desired shapes you don’t have to worry about underlining implementation of how the area is been calculated.

package OOPs

object Main extends App{
  val shape = new Shapes   
  println("Area of circle: " + shape.circle(4))

  val polygon = new TwoDShapes
  println("Area of equilateral triangle: " + polygon.triangle(2, 2))


Encapsulation in Object Oriented Programming

It is basically binding together fields and methods that manipulate your data and that keep both safes from outside interference and misuse.

This can be done using keywords like private and protected in Scala.

Encapsulation Example

package OOPs

trait ThreeDSpheres {
  private val pi = 3.1416

  def cylinder(h: Int, r: Int): Double = 2 * pi * r * (h + r)    //cylinder area


Inheritance in Object Oriented Programming

It is the most powerful feature and it basically allows you to have code reusability.

As an example, consider the case where you have an existing class and you want to build a new class that uses the previous class’s stuff, but adds additional features.

Classes that are derived from existing classes are either called subclass or child classes and the class from which that subclass can be derived is called superclass or parent class.

Inheritance Example

Taking the same area of shape example suppose you have two classes one is of Shapes which is implementing area of normal shapes and you have another class which implements the area of 3-D shapes now you can use some methods from Shapes class in order to calculate the area of 3-D shapes

package OOPs

class Shapes {
  private val pi = 3.1416

  def rectangle(a: Int, b: Int): Int = a * b
  def square(a: Int): Int = a * a
  def trapezium(a:Int, b: Int, h: Int): Double = 0.5 * (a + b) * h
  def triangle(h: Int, b: Int): Double = 0.5 * h * b
  def circle(r: Int): Double = pi * r * r

package OOPs

class ThreeDShapes extends Shapes with ThreeDSpheres {
  private val pi = 3.1416
  override def square(a: Int): Int = 6 * a * a    //cube
  override def trapezium(a: Int, b: Int, h: Int): Double = 2 * h * (a + b)  //csa Cuboid
  override def circle(r: Int): Double = 2 * r   //diameter
  override def cylinder(h: Int, r: Int): Double = pi * h * r * r     //cylinder volume

  def cone(slantHeight: Int, r: Int): Double = pi * r * slantHeight   //sa of cone


Polymorphism in Object Oriented Programming

Polymorphism is basically the combination of two words “Poly” which means Many and Morphwhich means Forms, yeah I know it sounds a little confusing so basically, it allows you to determine what kind of function to run while the program is running.

In Scala we can divide Polymorphism into the following types:

Parametric Polymorphism

It allows us to apply the same logic to different data types just like generics.

def pairReversing[Z](xs:List[Z]): List[Z] = xs.grouped(2).flatMap(_.reverse).toList

Subtype Polymorphism

A Scala function is said to be subtype polymorphism if at least one of its parameter types has subtypes based on the Liskov substitution principle.

This type of polymorphism is written as S <: T, which means S is a subtype of T or T :> S, meaning T is a supertype of S

trait Shape {
    def getArea: Double
case class Cube(side: Double) extends Shape {
    override def getVolume: Double = side * side * side
case class Cone(radius: Double, height: Double) extends Shape {
    private val pi = 3.124
    override def getVolume: Double =  0.333 * radius * radius * height

def printArea[T <: Shape](shape: T): Double = (math.floor(shape.getVolume) * 100)/100


Thank you for making it to the end of this blog on OOP I hope you got a basic understanding of the four pillars of object-oriented programming.


In order to get more coding examples related to the four pillars you can refer to the following link:



Written by 

Hi community, I am Raviyanshu from Dehradun a tech enthusiastic trying to make something useful with the help of 0 & 1.

Leave a Reply