An Easy Guide To The 4 Object-Oriented Programming Principles

4 Object-Oriented Programming Principles

Background

In a recent interview, I’ve been asked what object-oriented programming principles are and to give the interviewer some examples. Though object-oriented programming principles are almost one of the common interview questions, sometimes it’s challenging to provide the interviewer examples right at that moment (sadly, especially if you are nervous).

So, I decided to brush up on my memory of the 4 OOP principles using some examples that I worked through when I was in school.

Let’s get into it!

NOTE: Please note that the scope of this article is to understand what the 4 OOP principles are. Not to list the advantages or disadvantages of them.

4 OOP Principles

Here are the four principles:

1. Abstraction
2. Polymorphism
3. Inheritance
4. Encapsulation

If you shall make it as an acronym, “A PIE”!

Game Of Life

For the purpose of explaining these OOP principles, we are going to use “Game-Of-Life”. If you are not familiar with “Game-Of-Life”, it’s a game invented by John Conway, a mathematician. The details of the game can be found on this Wikipedia. You can also play the game from this site. However, in this article, we will make a bit of a change to the original game.

Game Set Up and Rules

If you are curious about the modified game set-up and rules, you can read the section “Game Setup and Rules” in this GitHub repo.
However, you should be able to understand the content of this article without reading the game setup and rules.

Pandas eating plant
Pandas eating plant – Photo by Richard Tao on Unsplash

Code Examples

If you want to see the full code, please visit the Game-Of-Life repo.

Abstraction

As the word suggests, abstraction means “Show the high-level only”. We are only interested in what we can use, not how.
The abstraction is a process of hiding the implementation details and showing what functionalities we can use.

Abstraction can be achieved using the abstract keyword on classes or methods, or the interface.
We will be focusing on using the abstract keyword in this article. The interface does the same thing as the abstract keyword, however, it forces you to implement every function in subclasses that implement the interface.

LifeForm.java

Herbivore.java

Here, the LifeForm is defined with the abstract keyword and the Herbivore is extending the LifeForm. The LifeForm is showing what methods (performAction, countEdible, and createLife) can be used and the Herbivore is showing how the methods can be used by providing the actual implementations. So, we can say (with confidence!) the LifeForm is the “high-level” of the Herbivore and that the abstraction has been applied to our code.

Polymorphism

The word “poly” means “many” and “morph” means “changing forms”. As these two words indicate, Polymorphism means that it can have multiple forms.

Ok, great, but how can it be achieved in Java?

Polymorphism can be achieved in two ways – method overriding and method overloading.

Let me explain what method overriding and method overloading are with some code examples.

Method Overriding

Method Overriding is quite literal. A method from the superclass can be “overridden” by a method from the subclass using the same method name.

LifeForm.java

Carnivore.java

Omnivore.java

The method createLife(Cell cell) in the LifeForm class is being overridden by the method createLife(Cell cell) in Carnivore or Omnivore classes. Notice that the methods have the exactly same name with a parameter.

NOTE: Don’t be afraid of the abstract keyword in front of the createLife(Cell cell) method. It still works the same as other regular methods. It is still method overriding.

Method Overloading

In our code, we are not really using method overloading, however, let’s make an assumption and imagine we have the code below.

LifeForm.java

In the code above, we are able to find two methods with the same name but different parameters. Even though they have the exact same name, it’s not a problem for Java to figure out which one to use as long as the user provides the correct parameters.

TIP: If you have a hard time remembering what method overloading is just by looking at the term, you can think of a method getting “overloaded” with parameters.

Inheritance

Inheritance is pretty straightforward. It means that the child class(s) (a.k.a. subclass) inherits a parent class (a.k.a. superclass). A child class inherits all fields, methods, and nested classes with the default(no-modifier)/protected/public access modifier of the parent class.

Inheriting Attribute

The attributes from the superclass can be accessed/used from subclasses by using the keyword super.

LifeForm.java

Herbivore.java

Whenever Herbivore object is created, it will store “cell” information passed as an argument. You might have noticed that we actually don’t have “cell” attribute in the Herbivore class. Even though there is no “cell” attribute in the Herbviore, we are able to store cell information in the “cell” attribute in the LifeForm by using super.cell = cell.

Inheriting Method (a.k.a. method overriding)

The methods can also be inherited from superclass to subclasses. A method in subclasses can override the implementation of the method that has the same name in the superclass.

LifeForm.java

Plant.java

Carnivore.java

NOTE: I made a slight change in LifeForm from the original code to explain one more detail.

The method performAction is being overridden by the subclasses Plant and Carnivore. When the method performAction is invoked, each lifeform would act differently. A Plant object will give birth, on the other hand, a Carnivore object will move first and then give birth. If you really want to invoke performAction method from LifeForm, you will be able to do so by doing super.performAction() in the subclasses.

As another example, the Plant and Carnivore subclasses inherit the method createLife from LifeForm. However, the actual implementation in both subclasses is different. It creates a new Plant object in the Plant subclass and a new Carnivore object in Carnivore subclass.

If you made it here, great job on following through!
Let’s take a look at our last principle “Encapsulation”.

Encapsulation

Again, Here is one of the definitions of Encapsulation on Google – the action of enclosing something in or as if in a capsule.
Imagine a capped pill with a capsule that contains powder medicine inside. If we don’t have a capsule protecting the powder, it will be blown away in a second. It’s the same concept in computer science as well. We encapsulate class members (whether it’s a variable or data) within that class.

By implementing encapsulation, we get the benefits of hiding and protecting fields from the outside of the class.

Let’s take a look at an example that doesn’t use encapsulation.

If a field has the public access modifier, then we would be able to access a field by creating an object of that class and using dot notation. However, it is never a good practice to overuse the public access modifier. It is always recommended to use the private access modifier and “encapsulate” the data within the class to keep the fields safe.

If we change the public access modifier to the private access modifier, we will be no longer able to access the field using dot notation. Then, how would we access the field in this case? We will create methods for reading and writing the field (a getter for reading and a setter for writing).

LifeForm.java

There are 2 fields defined as privateisAlive and moved. Since they have the private access modifier, they can’t be accessed directly from outside (i.e. lifeform.isAlive won’t work). For that reason, we created getters and setters for the fields. However, notice that we only have the setter for isAlive. This means isAlive will be “write-only”. This is one of the benefits of using encapsulation. We can pick and choose what to expose to the outside world.

Now, this concludes all 4 Obejct-Oriented Programming principles in Java.
Hopefully, the explanation with code examples helped you understand what they are and how they can be implemented.

Thank you for reading. If you have thoughts on this, be sure to leave a comment.

I also write articles on Medium, so make sure to check them out on medium/@codingnotes.

Happy coding!

Leave a Comment

Your email address will not be published. Required fields are marked *