DEV Community

loading...
Cover image for The Four Pillars of Object Oriented Programming

The Four Pillars of Object Oriented Programming

greedybrain profile image Naya Willis ・3 min read

In this blog I will explain the 4 pillars of OOP and provide small examples. Small enough examples that you and I can comprehend easily.

Abstraction

Abstraction is essentially "need to know". We hide the major implementation details, while keeping the obvious usage at the forefront. So remember this "hide the details, show the relevance".

Abstraction example...

This is a signup form of an app I'm working on (the relevance).

Alt Text

This is the form's submission implementation logic. (the need to know).

Alt Text

Alt Text

Polymorphism

Polymorphism is when you use one block of code, you change the version of the code being used based on the inputs being giving to it. So to make it a bit clearer, different classes can be used with the same interface but can provide its own implementation of that interface.

Polymorphism example...

class Animal {
  speak = () => console.log('makes sound')
}
class Dog extends Animal {
  speak = () => console.log('woof')
}

class Cat extends Animal {
  speak = () => console.log('meowww')
}

class Cow extends Animal {
  speak = () => console.log('moooooo')
}

let dog1 = new Dog()
let cat1 = new Cat()
let cow1 = new Cow()

dog1.speak() // => woof
cat1.speak() // => meowww
cow1.speak() // => moooooo
Enter fullscreen mode Exit fullscreen mode

The Cat, Dog, and Cow classes are inheriting from the Animal class. This allows the Cat, Dog, and Cow class to use the Animal's interface. They only have the speak method available to them though. If we were to leave the speak method out of the Cat, Dog, and Cow class, and then create instances of a Cat, Dog, and Cow class we would still be able to call the speak method on those instances. The only issue is that it would print out the Animals 'makes sound' instead of the appropriate sounds that a Cat, Dog, and Cow makes ('meow', 'woof', 'moo').

This is where method overriding comes in. If we redefine the speak method in the Cat, Dog, and Cow classes, we can customize it to print out the sounds that cats and dogs make.

Encapsulation

Encapsulation binds together the data and functions that manipulate the data, and that keeps both safe from outside interference and misuse. A good example of encapsulation is a class. We can actually refer back to the example above where we talk about Dogs, Cats, and Cows with some slight modifications.

class Dog {
  constructor(name) {
    this.name = name
  }
  printName = () => console.log(this.name)
}

class Cat {
  constructor(name) {
    this.name = name
  }
  printName = () => console.log(this.name)
}

class Cow {
  constructor(name) {
    this.name = name
  }
  printName = () => console.log(this.name)
}

let dog1 = new Dog()
dog1.name = "Max"
dog1.printName() // => Max

let cat1 = new Cat()
cat1.name = "Mark"
cat1.printName() // => Mark

let cow1 = new Cow()
cow1.name = "Tom"
cow1.printName() // => Tom
Enter fullscreen mode Exit fullscreen mode

Notice when we create instances for each animal we also assign a name to each. The takeaway here is that the '.name' after each created instances (i.e dog1.name) are all different. Those '.name' are encapsulated within their according classes. Assigning a name to an instance does not modify any other instances name value.

Inheritance

Inheritance is probably the most easiest one to grasp. Inheritance is the concept of one class using(inheriting) the interface of another class. It then becomes a child or subclass while the class that it's inheriting from is the parent or superclass. We actually did some inheriting in our second example above. The Cat, Dog, and Cow class inherits from the Animal class in order to have access to the speak method. Just make sure to add the extends keyword.

Thanks for reading, please do let me know if this was clear or not. Leave a comment below.

Discussion (13)

pic
Editor guide
Collapse
oguimbal profile image
Olivier Guimbal • Edited

Nice article. I'd add my 2 cents: While those features are often encountered in OO languages, they are not mandatory. For instance, GO is an OO language in some way, but it does not have inheritance.

And these pillars are not an uniquely OO feature. You'll also find them in FP (Functional Programming) languages. Except maybe for inheritance, which you will of course not find in purely FP languages (Haskell, Elm, ...) - but will find it in most of them as a result of their integration in an ecosystem (Scala, F#, ...).

Richard Feldman speaks about this in one of my favorite tech talks (specifically at 19:55, but the whole talk is really worth watching)

... That said, it does not take anything away from your article :) I just wanted to share this talk.

Collapse
bias profile image
Collapse
amaralani profile image
Amir Maralani • Edited

First of all thanks for a good post!
But in your encapsulation example, I see this :

let cat1 = new Dog()
...
let cow1 = new Dog()
Enter fullscreen mode Exit fullscreen mode

It works but I suggest you either initialize them from the corresponding classes or change the variable names (dog2, dog3) to make the code clean.

Collapse
greedybrain profile image
Naya Willis Author

Sorry, my mistake.

Collapse
dakujem profile image
Andrej Rypo

Your polymorphism example breaks the Liskov substitution principle. Just use composition and don't make cow1 instanceof Dog === true 🤦‍♂️ Did you study biology basics? 😉

Collapse
andreidascalu profile image
Andrei Dascalu

Principle are "stuff that helps more often than not", not pervasive absolutes on the same level as God's word. But more to the point, it would be weird to talk about inheritance as a "pillar" of oop when general practices have been recommending composition over inheritance for years.

Collapse
greedybrain profile image
Naya Willis Author

My bad, changed it to inherit from the Animal class. You happy now professor?

Collapse
dakujem profile image
Andrej Rypo

You're welcome. Just didn't want to write that the example missed the point completely, that's all. 🤷‍♂️ But you're definitely on a good path, keep going!

Collapse
andreidascalu profile image
Andrei Dascalu

Nice explanation, although as far as pillars are concerned, the main one in oop is the concept of objects. Hence the name.
Although as an interesting note, some of these pillars have been noted as broken for a while now (hence the slow ride of fp)

Collapse
stereobooster profile image
stereobooster

Encapsulation binds together the data and functions that manipulate the data,

this is definition of object (from OOP)

Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code: data in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).

Encapsulation

Encapsulation is a technique for minimizing interdependencies among separately-written modules by defining strict external interfaces. The external interface of a module serves as a contract between the module and its clients, and thus between the designer of the module and other designers. If clients depend only on the external interface, the module can be reimplemented without affecting any clients, so long as the new implementation supports the same (or an upward compatible) external interface. Thus, the effects of compatible changes can be confined.

-- cs.tufts.edu/comp/150CBD/readings/...

as well

encapsulate - to enclose in or as if in a capsule

-- merriam-webster.com/dictionary/enc...

Collapse
zoedreams profile image
Collapse
greedybrain profile image
Naya Willis Author

Thanks for sharing

Collapse
ben profile image
Ben Halpern

Nice post