OOP Concepts for System Design (original) (raw)

Last Updated : 16 Apr, 2026

Object-Oriented Programming (OOP) is a way of writing code by organizing it into objects and classes. It helps in making code more modular, reusable, and easy to manage. In simple terms, OOP focuses on creating objects that contain both data and behavior.

**Example: In a car system, a Car class can have properties like color and speed, and methods like start() and stop(). Different car objects (like BMW, Audi) can be created from the same class.

Types-of-OOPS-2

OOPs Concepts

Real-World Examples

OOP is widely used to model real-world systems by representing real entities as objects with classes and relationships.

Need of OOP

As software systems grow larger and multiple developers work on the same project, managing code becomes difficult without proper structure. OOP helps solve these problems by organizing code into modular and reusable components.

Classes and Objects in OOP

Classes and objects are fundamental concepts in object-oriented programming (OOP), which is a system design approach used to simulate real-world items and their interactions

1. Classes

A class is a template or blueprint used to create objects. It specifies the characteristics (properties) and actions (methods) that objects of that class will have.

**Attributes: Data an object holds (e.g., make, model, year in a Car class).
**Methods: Actions an object can perform (e.g., startEngine(), accelerate()).

Class_objects

Classes and Objects

2. Objects

An object is an instance of a class. It is created based on the blueprint defined by the class.

**Example:

C++ `

#include using namespace std;

class Student {

public: int roll; string name;

void takeLeave() {
    cout << "on leave" << endl;
}

void bunkClass() {
    cout << "Go out and play: " << endl;
}

};

int main() { Student sid; sid.bunkClass(); sid.name = "Siddhartha Hazra"; cout << sid.name << endl; return 0; }

C

#include <stdio.h> #include <string.h>

typedef struct Student { int roll; char name[50]; } Student;

void takeLeave(Student *s) { printf("on leave\n"); }

void bunkClass(Student *s) { printf("Go out and play: \n"); }

int main() { Student sid; bunkClass(&sid); strcpy(sid.name, "Siddhartha Hazra"); printf("%s\n", sid.name); return 0; }

Java

class Student {

int roll;
String name;

void takeLeave() {
    System.out.println("on leave");
}

void bunkClass() {
    System.out.println("Go out and play: ");
}

}

public class Main {

public static void main(String args[]) {

    Student sid = new Student();
    sid.bunkClass();
    sid.name = "Siddhartha Hazra";
    System.out.println(sid.name);
}

}

Python

class Student:

def __init__(self):
    self.roll = None
    self.name = None

def takeLeave(self):
    print("on leave")

def bunkClass(self):
    print("Go out and play: ")

sid = Student() sid.bunkClass() sid.name = "Siddhartha Hazra" print(sid.name)

JavaScript

class Student {

constructor() {
    this.roll = null;
    this.name = null;
}

takeLeave() {
    console.log('on leave');
}

bunkClass() {
    console.log('Go out and play: ');
}

}

const sid = new Student(); sid.bunkClass(); sid.name = 'Siddhartha Hazra'; console.log(sid.name);

`

Four Pillars of OOP

These are the core concepts that define Object-Oriented Programming and help in building structured and efficient code. They make systems more secure, reusable, and easy to maintain.

1. Encapsulation

Encapsulation is the process of combining data and methods for working with the data into a single unit called a class. It makes it possible to hide a class's implementation details from outside users who engage with the class via its public interface.

Encapsulation

Encapsulation

**Example:

C++ `

#include #include

class Employee { private: int id; std::string name;

public: void setId(int id) { this->id = id; }

void setName(std::string name) {
    this->name = name;
}

int getId() {
    return id;
}

std::string getName() {
    return name;
}

};

int main() { Employee emp;

// Using setters
emp.setId(101);
emp.setName("Geek");

// Using getters
std::cout << "Employee ID: " << emp.getId() << std::endl;
std::cout << "Employee Name: " << emp.getName() << std::endl;

return 0;

}

C

#include <stdio.h> #include <string.h>

typedef struct Employee { int id; char name[50]; } Employee;

void setId(Employee* emp, int id) { emp->id = id; }

void setName(Employee* emp, const char* name) { strcpy(emp->name, name); }

int getId(Employee* emp) { return emp->id; }

const char* getName(Employee* emp) { return emp->name; }

int main() { Employee emp;

// Using setters
setId(&emp, 101);
setName(&emp, "Geek");

// Using getters
printf("Employee ID: %d\n", getId(&emp));
printf("Employee Name: %s\n", getName(&emp));

return 0;

}

Java

class Employee { // Private fields (encapsulated data) private int id; private String name;

// Setter methods 
public void setId(int id) {
    this.id = id;
}

public void setName(String name) {
    this.name = name;
}

// Getter methods
public int getId() {
    return id;
}

public String getName() {
    return name;
}

}

public class Main { public static void main(String[] args) { Employee emp = new Employee();

    // Using setters
    emp.setId(101);
    emp.setName("Geek");

    // Using getters
    System.out.println("Employee ID: " + emp.getId());
    System.out.println("Employee Name: " + emp.getName());
}

}

Python

class Employee: def init(self): self.__id = None self.__name = None

def set_id(self, id):
    self.__id = id

def set_name(self, name):
    self.__name = name

def get_id(self):
    return self.__id

def get_name(self):
    return self.__name

emp = Employee()

Using setters

emp.set_id(101) emp.set_name("Geek")

Using getters

print(f'Employee ID: {emp.get_id()}') print(f'Employee Name: {emp.get_name()}')

JavaScript

class Employee { constructor() { this.id = null; this.name = null; }

setId(id) {
    this.id = id;
}

setName(name) {
    this.name = name;
}

getId() {
    return this.id;
}

getName() {
    return this.name;
}

}

const emp = new Employee();

// Using setters emp.setId(101); emp.setName('Geek');

// Using getters console.log('Employee ID: ' + emp.getId()); console.log('Employee Name: ' + emp.getName());

`

2. Abstraction

Abstraction is the process of concentrating on an object's or system's key features while disregarding unimportant elements. It enables programmers to produce models that simply and easily convey the core of real-world objects and ideas. We can achieve abstraction in two ways:

abstraction_in_object_oriented_programming

Abstraction

**Example:

C++ `

#include

// Abstract class class Vehicle { public: // Pure virtual functions virtual void accelerate() = 0; virtual void brake() = 0;

// Concrete method
void startEngine() {
    std::cout << "Engine started!" << std::endl;
}

};

// Concrete class class Car : public Vehicle { public: void accelerate() override { std::cout << "Car: Pressing gas pedal..." << std::endl; // Hidden complex logic: fuel injection, gear shifting, etc. }

void brake() override {
    std::cout << "Car: Applying brakes..." << std::endl;
    // Hidden logic: hydraulic pressure, brake pads, etc.
}

};

int main() { Vehicle* myCar = new Car(); myCar->startEngine(); myCar->accelerate(); myCar->brake(); delete myCar; return 0; }

C

#include <stdio.h>

// Abstract class equivalent using struct and function pointers typedef struct { void (accelerate)(struct Vehicle); void (brake)(struct Vehicle); void (startEngine)(struct Vehicle); } Vehicle;

// Concrete methods void startEngine(Vehicle* self) { printf("Engine started!\n"); }

void carAccelerate(Vehicle* self) { printf("Car: Pressing gas pedal...\n"); // Hidden complex logic: fuel injection, gear shifting, etc. }

void carBrake(Vehicle* self) { printf("Car: Applying brakes...\n"); // Hidden logic: hydraulic pressure, brake pads, etc. }

int main() { Vehicle myCar = { .accelerate = carAccelerate, .brake = carBrake, .startEngine = startEngine }; myCar.startEngine(&myCar); myCar.accelerate(&myCar); myCar.brake(&myCar); return 0; }

Java

abstract class Vehicle { // Abstract methods (what it can do) abstract void accelerate(); abstract void brake();

// Concrete method (common to all vehicles)
void startEngine() {
    System.out.println("Engine started!");
}

}

// Concrete implementation (hidden details) class Car extends Vehicle { @Override void accelerate() { System.out.println("Car: Pressing gas pedal..."); // Hidden complex logic: fuel injection, gear shifting, etc. }

@Override
void brake() {
    System.out.println("Car: Applying brakes...");
    // Hidden logic: hydraulic pressure, brake pads, etc.
}

}

public class Main { public static void main(String[] args) { Vehicle myCar = new Car(); myCar.startEngine();
myCar.accelerate();
myCar.brake();
} }

Python

from abc import ABC, abstractmethod

Abstract class

class Vehicle(ABC): @abstractmethod def accelerate(self): pass

@abstractmethod
def brake(self):
    pass

def startEngine(self):
    print("Engine started!")

Concrete class

class Car(Vehicle): def accelerate(self): print("Car: Pressing gas pedal...") # Hidden complex logic: fuel injection, gear shifting, etc.

def brake(self):
    print("Car: Applying brakes...")
    # Hidden logic: hydraulic pressure, brake pads, etc.

Main execution

if name == "main": myCar = Car() myCar.startEngine() myCar.accelerate() myCar.brake()

JavaScript

// Abstract class class Vehicle { constructor() { if (this.constructor === Vehicle) { throw new Error("Abstract classes can't be instantiated."); } }

// Abstract methods
accelerate() {
    throw new Error("Method 'accelerate()' must be implemented.");
}

brake() {
    throw new Error("Method 'brake()' must be implemented.");
}

// Concrete method
startEngine() {
    console.log('Engine started!');
}

}

// Concrete class class Car extends Vehicle { accelerate() { console.log('Car: Pressing gas pedal...'); // Hidden complex logic: fuel injection, gear shifting, etc. }

brake() {
    console.log('Car: Applying brakes...');
    // Hidden logic: hydraulic pressure, brake pads, etc.
}

}

// Main execution const myCar = new Car(); myCar.startEngine(); myCar.accelerate(); myCar.brake();

`

3. Inheritance

A class (subclass or derived class) can inherit properties and methods from another class (superclass or base class) through inheritance. While retaining its common characteristics, the subclass has the ability to add or change the superclass's functionality.

inheritance-660x454

Inheritance

**Syntax:

// Superclass
class Superclass {
// Superclass members
}

// Subclass
class Subclass extends Superclass {
// Subclass members
}

**Example:

C++ `

// Superclass (Parent) #include class Animal { public: void eat() { std::cout << "Animal is eating..." << std::endl; }

void sleep() {
    std::cout << "Animal is sleeping..." << std::endl;
}

};

// Subclass (Child) - Inherits from Animal class Dog : public Animal { public: void bark() { std::cout << "Dog is barking!" << std::endl; } };

int main() { Dog myDog;

// Inherited methods (from Animal)
myDog.eat();
myDog.sleep();

// Child class method
myDog.bark();
return 0;

}

C

// Superclass (Parent) #include <stdio.h>

void eat() { printf("Animal is eating...\n"); }

void sleep() { printf("Animal is sleeping...\n"); }

void bark() { printf("Dog is barking!\n"); }

int main() { // Inherited methods (from Animal) eat(); sleep();

// Child class method
bark();
return 0;

}

Java

// Superclass (Parent) class Animal { void eat() { System.out.println("Animal is eating..."); }

void sleep() {
    System.out.println("Animal is sleeping...");
}

}

// Subclass (Child) - Inherits from Animal class Dog extends Animal { void bark() { System.out.println("Dog is barking!"); } }

public class Main { public static void main(String[] args) { Dog myDog = new Dog();

    // Inherited methods (from Animal)
    myDog.eat();    
    myDog.sleep();  

    // Child class method
    myDog.bark();   
}

}

Python

Superclass (Parent)

class Animal: def eat(self): print("Animal is eating...")

def sleep(self):
    print("Animal is sleeping...")

Subclass (Child) - Inherits from Animal

class Dog(Animal): def bark(self): print("Dog is barking!")

Main

if name == 'main': myDog = Dog()

# Inherited methods (from Animal)
myDog.eat()
myDog.sleep()

# Child class method
myDog.bark()

JavaScript

// Superclass (Parent) class Animal { eat() { console.log('Animal is eating...'); }

sleep() {
    console.log('Animal is sleeping...');
}

}

// Subclass (Child) - Inherits from Animal class Dog extends Animal { bark() { console.log('Dog is barking!'); } }

// Main const myDog = new Dog();

// Inherited methods (from Animal) myDog.eat(); myDog.sleep();

// Child class method myDog.bark();

`

4. Polymorphism

It makes code reuse, extension and flexibility possible by treating objects of different classes as belonging to the same superclass. Through a standard interface, it enables uniform treatment of objects of various categories. It allows the same code to work with several kinds of objects.

polymorphism

Polymorphism

**Example:

C++ `

#include

class Calculator { public: // Method for adding two integers int add(int a, int b) { return a + b; }

// Overloaded method for adding three integers
int add(int a, int b, int c) {
    return a + b + c;
}

// Overloaded method for adding two doubles
double add(double a, double b) {
    return a + b;
}

};

int main() { Calculator myCalculator;

// Example usage of the overloaded methods
int sum1 = myCalculator.add(5, 3);
int sum2 = myCalculator.add(4, 6, 2);
double sum3 = myCalculator.add(3.5, 2.7);

// Output the results
std::cout << "Sum of 5 and 3: " << sum1 << std::endl;
std::cout << "Sum of 4, 6, and 2: " << sum2 << std::endl;
std::cout << "Sum of 3.5 and 2.7: " << sum3 << std::endl;

return 0;

}

C

#include <stdio.h>

int add_int(int a, int b) { return a + b; }

int add_int_three(int a, int b, int c) { return a + b + c; }

double add_double(double a, double b) { return a + b; }

int main() { // Example usage of the functions int sum1 = add_int(5, 3); int sum2 = add_int_three(4, 6, 2); double sum3 = add_double(3.5, 2.7);

// Output the results
printf("Sum of 5 and 3: %d\n", sum1);
printf("Sum of 4, 6, and 2: %d\n", sum2);
printf("Sum of 3.5 and 2.7: %.1f\n", sum3);

return 0;

}

Java

public class Calculator { // Method for adding two integers public int add(int a, int b) { return a + b; }

// Overloaded method for adding three integers
public int add(int a, int b, int c) {
    return a + b + c;
}

// Overloaded method for adding two doubles
public double add(double a, double b) {
    return a + b;
}

public static void main(String[] args) {
    Calculator myCalculator = new Calculator();

    // Example usage of the overloaded methods
    int sum1 = myCalculator.add(5, 3);
    int sum2 = myCalculator.add(4, 6, 2);
    double sum3 = myCalculator.add(3.5, 2.7);

    // Output the results
    System.out.println("Sum of 5 and 3: " + sum1);
    System.out.println("Sum of 4, 6, and 2: " + sum2);
    System.out.println("Sum of 3.5 and 2.7: " + sum3);
}

}

JavaScript

class Calculator { // Method for adding two integers add(a, b) { return a + b; }

// Overloaded method for adding three integers
add(a, b, c) {
    if (arguments.length === 3) {
        return a + b + c;
    }
    return this.add(a, b);
}

// Overloaded method for adding two doubles
add(a, b) {
    if (typeof a === 'number' && typeof b === 'number') {
        return a + b;
    }
    return this.add(a, b);
}

}

const myCalculator = new Calculator();

// Example usage of the overloaded methods const sum1 = myCalculator.add(5, 3); const sum2 = myCalculator.add(4, 6, 2); const sum3 = myCalculator.add(3.5, 2.7);

// Output the results console.log('Sum of 5 and 3:', sum1); console.log('Sum of 4, 6, and 2:', sum2); console.log('Sum of 3.5 and 2.7:', sum3);

`

**Note: Python does not support method overloading in the same direct way that languages like Java or C++ do. Here, only the last definition will be accessible and callable as it "override" any previously defined methods with the same name.

Next Reads :