Important Concepts of Object-Oriented system (Part I)

Introduction

My intention toward this article is to share my thoughts and understanding of OOP in terms of programming.

Object-Oriented Programming: — A paradigm for writing good programs for a set of problems. This paradigm based on objects which contains information of its state (i.e. data) and behaviour (i.e. Methods).

According to Grady Booch, the conceptual framework of object model segregated the elements into two distinct pillars: -

· Major Pillars (or elements)

· Minor Pillars (or elements)

Major pillars consist of the following elements: -

1. Abstraction

2. Encapsulation

3. Modularity

4. Hierarchy

[ By major pillar, I mean that a model without any one of these elements is not object-oriented.]

Minor pillars consist of the following elements: -

5. Typing (Polymorphism)

6. Concurrency

7. Persistence

[By minor pillar, I Mean that each of this element is a useful, but not an essential part of the object model. We can treat them as supporting aspects.]

As I’m polyglot developer So I’ll try to cover all the topics for Java and .NET developers. Let’s start with the first topic.

1. Abstraction: -

Abstract — Existing in thoughts or as an idea but not a physical or concrete existence.

An abstraction denotes the essential features of a class that distinguish it from all other kinds of classes and thus provide crisply defined conceptual boundaries, relative to the perspective of the viewer.

Programmatically, we can achieve abstraction as follows: -

a. Abstract class, method (0 to 100%)

b. Interface. (100%)

EX: -

//Report.java
package com.thirstybrain.Model;
import java.util.List;
public interface Report {
List<Object> run(ReportContext reportContext);
}
//ReportContext.java
package com.thirstybrain.Model;
public class ReportContext {
}
//EmployeeReport.java
package com.thirstybrain.Model;
import java.util.List;
public class EmployeeReport implements Report{
@Override
public List<Object> run(ReportContext reportContext{
System.out.println("Executing EmployeeReport");
return null;
}
}
//SalaryReport.java
package com.thirstybrain.Model;
import java.util.List;
public class SalaryReport implements Report {
@Override
public List<Object> run(ReportContext reportContext) {
System.out.println("Executing SalaryReport");
return null;
}
}
//Employee.java
import com.thirstybrain.Model.EmployeeReport;
import com.thirstybrain.Model.Report;
import com.thirstybrain.Model.ReportContext;
import com.thirstybrain.Model.SalaryReport;
public class Employee{public static void main(String[] args) {ReportContext reportContext =new ReportContext();
Report ereport = new EmployeeReport();
ereport.run(reportContext);
//Output : Executing EmployeeReport
Report sreport = new SalaryReport();
sreport.run(reportContext);
//Output : Executing SalaryReport
}
}

Information Hiding: — Its interface or definition was chosen to reveal as little as possible about its inner working. Abstraction can be used as techniques for identifying which information should be hidden.

Programmatically we can achieve it by implementing Encapsulation via POJO classes. Data hiding has to do with the instance variables which decides the state of the Object. Hiding its content using mutators (i.e. setters and getters method).

EX:-

public class Person  {
private int age;
private String name;
public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
// getter can restrict the code without displaying
// data to the user
if(condition){//restricted user check
return null;
//returning null because the user is not
//supposed to view the data
}
return name;
}
}

2. Encapsulation:

En + Capsulate = wrapping (conceptually) data member and member function in a single unit.

It is basically to provide controlled access over a class by as follows: -

a. Access modifiers — To access data member and member function.

b. Mutators — To change and access data members value.

EX: -

public class Person  {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

public String getName() {
// getter can restrict the code without displaying
// data to the user
if(condition){//restricted user check
return null;
//returning null because the user
// is not supposed to view the data
}
return name;
}
public void setName(string name) {
this.name = name;
}
}
public class Employee {public static void main(String[] args) {Person personObj=new Person();
personObj.setName(“Prabhat”);
personObj.setAge(“40”);
System.out.println(“Name : ”+ personObj.getName() + “ Age : ”+ personObj.getAge())
}
}

By using Access modifiers, we are declaring data members with private access modifier. So any other class can’t directly access these data members. If we will use protected access modifier, then only inherited class can be able to access the data members and if we use public then anyone can be able to access.

Many people have a concern that we have access modifier to provide controlled access over data member then what is the need of mutators (I.e. getters and setters) function?

Data members are the internal property of a class. Once we expose the internals of class we can’t change internal representation or make it better until making a change in all the client code. And, this approach has its own overhead. If we access data members outside using getters and setters then if we want to change or impose constraints (i.e. validations, conversion, etc.) on the data members, we can write that code inside mutators and it will be applied to all the client code automatically. There may be the possibility that get may be public, but the set could be protected. In pure object-oriented world getters and setters is an anti-pattern.

There are a few programmers in the community who believe that getters and setters are bad object-oriented design. But, in me believe adding getters and setters for all data members automatically is bad practice without analyzing, whether that getter or setter is needed or not because this basically exposes class’s implementation to the outside world, violating the information hiding and abstraction. Many times this practice we are seeing while generating getters and setters through IDE’s.

Conclusion

If I have to summarize Abstraction, Encapsulation and Data hiding in a few words then it is something as below: -

Abstraction is more about “What” a class can do.

Encapsulation is more about “How” to achieve functionality.

Information hiding is more about “What is accessible and How much accessible for Whom”.

Technical Consultant | Passionate about exploring new Technology | Cyber Security Enthusiast | Technical Blogger | Problem Solver