OOP (Object-Oriented Programming) is a programming paradigm that treats everything as an object. OOP means considering every thing as an object and each object has properties and behaviors :
for example a
phone can turn on and off or take pictures, these are behaviors but it also has a brand like a samsung phone, now in
terms of programming we can say phone has a TurnOn/TurnOff function and a TakePicture function and also has a string variable as its brand name.
Why OOP?
OOP helps organize code by modeling real-world entities as software objects. This makes programs easier to build, manage, and extend.
Benefits of OOP
Procedural vs OOP
Procedural programming focuses on functions and step-by-step instructions, treating data as separate. Object-oriented programming (OOP) focuses on objects that bundle data and behavior, making code more modular and reusable.
Defenition
Class have behaviors and properties and its basically the object that we talked about in the last example.
You can create variables and functions for it and use them once you created an instance of it.
class ClassName {
public:
// Public data members
int x;
// Public member function
void show() {
std::cout << "x = " << x << std::endl;
}
private:
// Private data members (not accessible outside directly)
int secret;
// Private member function
void hide() {
std::cout << "This is private" << std::endl;
}
};
Once a class is defined, you can create objects (instances) of that class and use their properties and functions.
class Car {
public:
std::string brand;
void honk() {
std::cout << "Beep! Beep!" << std::endl;
}
};
int main() {
Car myCar; // Create an object of class Car
myCar.brand = "Toyota"; // Access data member
myCar.honk(); // Call member function
std::cout << "Brand: " << myCar.brand << std::endl;
return 0;
}
Access specifiers control the visibility of class members (variables and functions).
Example:
class Example {
public:
int publicVar; // accessible everywhere
private:
int privateVar; // accessible only inside Example
protected:
int protectedVar; // accessible in Example and derived classes
};
In a class, data members store the attributes (variables), and member functions define behaviors (functions) related to the class.
Example:
class Person {
public:
// Data members (attributes)
std::string name;
int age;
// Member function (behavior)
void introduce() {
std::cout << "Hello, my name is " << name
<< " and I am " << age << " years old." << std::endl;
}
};
Constructor is a function where it will be called when ever an object is created(at the same line). It is mostly used for setting default values or give vales to your data members.
Destructor is a function where it will be called when ever an object's lifetime is over(usually end of brackets). It is mostly used for deleting pointers and memories.
Default Constructor
class Example {
public:
Example() { // runs automatically when object created
std::cout << "Default constructor called" << std::endl;
}
};
Parameterized Constructor
class Example {
public:
int x;
Example(int val) { // initialize x with val
x = val;
}
};
int main(){
Example test(1);
}
Destructor
class Example {
public:
~Example() { // runs when object is destroyed
std::cout << "Destructor called" << std::endl;
}
};
Encapsulation means hiding internal data and only allowing access through controlled methods.
It is used so the user doesn't get direct access to your variables(secutity stuff...)
class Person {
private:
std::string name; // private: hidden from outside code
public:
void setName(std::string newName) { // setter to change name safely
name = newName;
}
std::string getName() { // getter to read name safely
return name;
}
};
Abstraction means hiding the complex details inside a class and showing only the essential features to the user.
It helps us use objects without worrying about how they work internally.
class Car {
public:
void start() {
// Complex internal details hidden from the user
std::cout << "Car started" << std::endl;
}
void drive() {
std::cout << "Car is driving" << std::endl;
}
};
int main() {
Car myCar;
myCar.start(); // User just calls start without knowing internals
myCar.drive();
return 0;
}
Inheritance lets a class (child) use the properties and functions of another class (parent).
class Animal {
public:
void speak() {
std::cout << "Animal speaks" << std::endl;
}
};
class Dog : public Animal { // Dog inherits from Animal
};
int main() {
Dog d;
d.speak(); // Inherited from Animal
}
class Animal {
public:
void sound() { std::cout << "Some sound" << std::endl; }
};
class Dog : public Animal {};
class Puppy : public Dog {}; // Puppy inherits from Dog which inherits from Animal
int main() {
Puppy p;
p.sound();
}
class Fly {
public:
void canFly() { std::cout << "I can fly" << std::endl; }
};
class Walk {
public:
void canWalk() { std::cout << "I can walk" << std::endl; }
};
class Bird : public Fly, public Walk {};
int main() {
Bird b;
b.canFly();
b.canWalk();
}
protected
members act like private
, but derived classes can access them.
class Base {
public:
Base() { std::cout << "Base constructor" << std::endl; }
};
class Derived : public Base {
public:
Derived() { std::cout << "Derived constructor" << std::endl; }
};
int main() {
Derived obj; // First Base(), then Derived()
}
class Base {
public:
void show() { std::cout << "Base" << std::endl; }
};
class Derived : public Base {
public:
void show() { std::cout << "Derived" << std::endl; } // overrides Base::show
};
Polymorphism means "many forms" — the same function behaves differently in different situations.
class Print {
public:
void show(int x) {
std::cout << "Integer: " << x << std::endl;
}
void show(std::string text) {
std::cout << "String: " << text << std::endl;
}
};
class Point {
public:
int x;
Point(int val) { x = val; }
// Overloading + operator
Point operator+(const Point& p) {
return Point(x + p.x);
}
};
class Base {
public:
virtual void speak() {
std::cout << "Base speaking" << std::endl;
}
};
class Derived : public Base {
public:
void speak() override {
std::cout << "Derived speaking" << std::endl;
}
};
int main() {
Base* ptr = new Derived();
ptr->speak(); // Calls Derived version due to virtual function
}
We can use a base class pointer to point to derived objects and call overridden functions.
class Shape {
public:
virtual void draw() = 0; // Pure virtual = must be overridden
};
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing circle" << std::endl;
}
};
class Box {
private:
int width;
public:
Box() { width = 0; }
// Friend function
friend void setWidth(Box& b, int w);
};
void setWidth(Box& b, int w) {
b.width = w;
}
class Counter {
public:
static int count;
Counter() { count++; }
static void showCount() {
std::cout << "Count: " << count << std::endl;
}
};
int Counter::count = 0;
class MyClass {
private:
int value;
public:
void setValue(int value) {
this->value = value;
}
MyClass& returnSelf() {
return *this;
}
};
class Example {
public:
int* ptr;
Example() {
ptr = new int;
*ptr = 10;
}
~Example() {
delete ptr;
}
};
class Engine {
public:
void start() {
std::cout << "Engine started" << std::endl;
}
};
class Car {
private:
Engine engine; // Composition
public:
void startCar() {
engine.start();
}
};
namespace MySpace {
void greet() {
std::cout << "Hello from MySpace!" << std::endl;
}
}
using namespace MySpace;
int main() {
greet(); // Calls MySpace::greet
}
template< typename T >
T add(T a, T b) {
return a + b;
}
template< class T>
class Box {
private:
T value;
public:
Box(T v) : value(v) {}
T getValue() { return value; }
};