๐๏ธ
Chapter 3
Object-Oriented Programming
Learn OOP principles including classes, objects, encapsulation, inheritance, and polymorphism.
3.1 Class and Object Concepts
Understanding the fundamental building blocks of object-oriented programming.
| Aspect | Definition | Example |
|---|---|---|
| Class | Blueprint for creating objects. |
class Car { public: int wheels; };
|
| Object | Instance of a class. |
Car myCar;
|
| Members | Attributes and methods of a class. |
int wheels; void drive();
|
| Access Specifiers | Control visibility of members. |
public, private, protected
|
| Object Initialization | Setting initial values for an object. |
Car myCar = {4};
|
โถ Classes and Objects Example
#include <iostream>
using namespace std;
// Class definition
class Tesla {
private:
int batteryLevel;
string model;
public:
// Constructor
Tesla(string m, int battery) {
model = m;
batteryLevel = battery;
}
// Methods
void displayInfo() {
cout << "Tesla " << model << endl;
cout << "Battery: " << batteryLevel << "%" << endl;
}
void charge(int amount) {
batteryLevel += amount;
if(batteryLevel > 100) batteryLevel = 100;
cout << "Charged! Battery now at " << batteryLevel << "%" << endl;
}
void drive(int distance) {
int consumption = distance / 5;
batteryLevel -= consumption;
if(batteryLevel < 0) batteryLevel = 0;
cout << "Drove " << distance << " km. Battery: " << batteryLevel << "%" << endl;
}
};
int main() {
// Create objects
Tesla model3("Model 3", 80);
Tesla modelS("Model S", 90);
model3.displayInfo();
model3.drive(100);
model3.charge(30);
cout << endl;
modelS.displayInfo();
return 0;
}
Click "Run Code" to execute
3.2 Encapsulation and Inheritance
Core OOP principles for data hiding and code reusability.
| Aspect | Definition | Example |
|---|---|---|
| Encapsulation | Wrapping data and methods in a single unit. |
class Tesla { private: int battery; };
|
| Data Hiding | Restricting access using access specifiers. |
private int battery;
|
| Inheritance | Mechanism to derive new class from existing class. |
class EV : public Car { };
|
| Single Inheritance | One derived class inherits from one base class. |
class Derived : public Base { };
|
| Multiple Inheritance | A class inherits from multiple base classes. |
class C : public A, public B { };
|
โถ Encapsulation Example
#include <iostream>
using namespace std;
class BankAccount {
private:
double balance; // Encapsulated data
string accountNumber;
public:
// Constructor
BankAccount(string accNum, double initialBalance) {
accountNumber = accNum;
balance = initialBalance;
}
// Public methods to access private data
void deposit(double amount) {
if(amount > 0) {
balance += amount;
cout << "Deposited: $" << amount << endl;
}
}
void withdraw(double amount) {
if(amount > 0 && amount <= balance) {
balance -= amount;
cout << "Withdrawn: $" << amount << endl;
} else {
cout << "Insufficient funds!" << endl;
}
}
double getBalance() {
return balance;
}
void displayInfo() {
cout << "Account: " << accountNumber << endl;
cout << "Balance: $" << balance << endl;
}
};
int main() {
BankAccount myAccount("ACC369", 1000.0);
myAccount.displayInfo();
myAccount.deposit(500);
myAccount.withdraw(300);
myAccount.displayInfo();
// myAccount.balance = 10000; // Error: cannot access private member
return 0;
}
Click "Run Code" to execute
โถ Inheritance Example
#include <iostream>
using namespace std;
// Base class
class Vehicle {
protected:
string brand;
int year;
public:
Vehicle(string b, int y) : brand(b), year(y) {}
void displayBasicInfo() {
cout << "Brand: " << brand << endl;
cout << "Year: " << year << endl;
}
};
// Derived class - Single Inheritance
class Car : public Vehicle {
private:
int doors;
public:
Car(string b, int y, int d) : Vehicle(b, y) {
doors = d;
}
void displayCarInfo() {
displayBasicInfo();
cout << "Doors: " << doors << endl;
}
};
// Further derived class
class ElectricCar : public Car {
private:
int batteryCapacity;
public:
ElectricCar(string b, int y, int d, int battery)
: Car(b, y, d) {
batteryCapacity = battery;
}
void displayFullInfo() {
displayCarInfo();
cout << "Battery: " << batteryCapacity << " kWh" << endl;
}
};
int main() {
ElectricCar tesla("Tesla", 2024, 4, 100);
cout << "Electric Car Information:" << endl;
tesla.displayFullInfo();
return 0;
}
Click "Run Code" to execute
๐ณ Inheritance Hierarchy Visualization
3.3 Abstract Classes
Classes that cannot be instantiated and serve as base for derived classes.
| Aspect | Definition | Example |
|---|---|---|
| Abstract Class | Class that cannot be instantiated. |
class Abstract { virtual void func() = 0; };
|
| Pure Virtual Function | Declared but not defined in base class. |
virtual void display() = 0;
|
| Use Case | Provides a base for polymorphism. |
Base class for derived classes
|
| Derived Class | Must implement pure virtual functions. |
class Derived : public Abstract { };
|
| Virtual Keyword | Ensures function overriding. |
virtual void show();
|
โถ Abstract Classes Example
#include <iostream>
using namespace std;
// Abstract base class
class Shape {
protected:
string color;
public:
Shape(string c) : color(c) {}
// Pure virtual functions
virtual double area() = 0;
virtual double perimeter() = 0;
virtual void display() = 0;
// Regular virtual function
virtual void setColor(string c) {
color = c;
}
};
// Derived class - Circle
class Circle : public Shape {
private:
double radius;
public:
Circle(string c, double r) : Shape(c), radius(r) {}
double area() override {
return 3.14159 * radius * radius;
}
double perimeter() override {
return 2 * 3.14159 * radius;
}
void display() override {
cout << color << " Circle" << endl;
cout << "Radius: " << radius << endl;
cout << "Area: " << area() << endl;
cout << "Perimeter: " << perimeter() << endl;
}
};
// Derived class - Rectangle
class Rectangle : public Shape {
private:
double length, width;
public:
Rectangle(string c, double l, double w)
: Shape(c), length(l), width(w) {}
double area() override {
return length * width;
}
double perimeter() override {
return 2 * (length + width);
}
void display() override {
cout << color << " Rectangle" << endl;
cout << "Length: " << length << ", Width: " << width << endl;
cout << "Area: " << area() << endl;
cout << "Perimeter: " << perimeter() << endl;
}
};
int main() {
// Shape s; // Error: cannot instantiate abstract class
Circle circle("Red", 5.0);
Rectangle rect("Blue", 4.0, 6.0);
circle.display();
cout << endl;
rect.display();
// Polymorphism with abstract class
Shape* shapes[2];
shapes[0] = &circle;
shapes[1] = ▭
cout << endl << "Using polymorphism:" << endl;
for(int i = 0; i < 2; i++) {
shapes[i]->display();
cout << endl;
}
return 0;
}
Click "Run Code" to execute
3.4 Polymorphism (Compile-Time and Run-Time)
Ability to process objects differently based on their type.
| Aspect | Definition | Example |
|---|---|---|
| Polymorphism | Process objects differently based on type. |
Compile-time and run-time polymorphism
|
| Compile-Time Polymorphism | Achieved via function or operator overloading. |
int add(int a, int b); float add(float x, float y);
|
| Run-Time Polymorphism | Achieved via method overriding. |
Using virtual functions
|
| Virtual Function | Enables run-time polymorphism. |
virtual void display();
|
| Overriding | Redefining base class methods in derived class. |
void display() override;
|
โถ Compile-Time Polymorphism (Overloading)
#include <iostream>
using namespace std;
// Compile-time polymorphism - Function Overloading
class Calculator {
public:
// Overloaded functions
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
string add(string a, string b) {
return a + b;
}
};
int main() {
Calculator calc;
cout << "Integer addition: " << calc.add(10, 20) << endl;
cout << "Double addition: " << calc.add(3.5, 2.5) << endl;
cout << "Three integers: " << calc.add(1, 2, 3) << endl;
cout << "String concatenation: " << calc.add("Hello", "World") << endl;
return 0;
}
Click "Run Code" to execute
โถ Run-Time Polymorphism (Virtual Functions)
#include <iostream>
using namespace std;
// Run-time polymorphism - Virtual Functions
class Animal {
public:
virtual void makeSound() {
cout << "Some generic animal sound" << endl;
}
virtual void move() {
cout << "Animal moves" << endl;
}
};
class Dog : public Animal {
public:
void makeSound() override {
cout << "Woof! Woof!" << endl;
}
void move() override {
cout << "Dog runs on four legs" << endl;
}
};
class Cat : public Animal {
public:
void makeSound() override {
cout << "Meow! Meow!" << endl;
}
void move() override {
cout << "Cat walks gracefully" << endl;
}
};
class Bird : public Animal {
public:
void makeSound() override {
cout << "Tweet! Tweet!" << endl;
}
void move() override {
cout << "Bird flies in the sky" << endl;
}
};
int main() {
// Runtime polymorphism
Animal* animals[3];
Dog dog;
Cat cat;
Bird bird;
animals[0] = &dog;
animals[1] = &cat;
animals[2] = &bird;
cout << "Demonstrating Runtime Polymorphism:" << endl;
for(int i = 0; i < 3; i++) {
animals[i]->makeSound();
animals[i]->move();
cout << endl;
}
return 0;
}
Click "Run Code" to execute
๐ก Practice Exercise
Master OOP concepts with these exercises:
- Create a class hierarchy for different types of vehicles
- Implement encapsulation in a Student class with private data
- Create an abstract class and derive multiple classes from it
- Demonstrate both compile-time and run-time polymorphism
- Build a simple banking system using OOP principles