Introduction

Encapsulation and abstraction are two fundamental concepts in Object-Oriented Programming (OOP) that help in building robust and maintainable software. This section will cover:

  • The definition and importance of encapsulation.
  • The definition and importance of abstraction.
  • Practical examples demonstrating these concepts.
  • Exercises to reinforce understanding.

Encapsulation

Definition

Encapsulation is the process of bundling the data (variables) and the methods (functions) that operate on the data into a single unit, known as a class. It also involves restricting direct access to some of the object's components, which is a means of preventing accidental interference and misuse of the data.

Key Points

  • Data Hiding: Encapsulation allows the internal representation of an object to be hidden from the outside. Only the necessary information is exposed.
  • Access Modifiers: C++ provides access modifiers (private, protected, and public) to control the visibility of class members.

Example

#include <iostream>
using namespace std;

class Employee {
private:
    string name;
    int age;
    double salary;

public:
    // Constructor
    Employee(string n, int a, double s) : name(n), age(a), salary(s) {}

    // Getter for name
    string getName() {
        return name;
    }

    // Setter for name
    void setName(string n) {
        name = n;
    }

    // Getter for age
    int getAge() {
        return age;
    }

    // Setter for age
    void setAge(int a) {
        if (a > 0) {
            age = a;
        }
    }

    // Getter for salary
    double getSalary() {
        return salary;
    }

    // Setter for salary
    void setSalary(double s) {
        if (s > 0) {
            salary = s;
        }
    }

    // Display employee details
    void display() {
        cout << "Name: " << name << ", Age: " << age << ", Salary: $" << salary << endl;
    }
};

int main() {
    Employee emp("John Doe", 30, 50000);
    emp.display();

    // Modify employee details using setters
    emp.setName("Jane Doe");
    emp.setAge(28);
    emp.setSalary(55000);
    emp.display();

    return 0;
}

Explanation

  • Private Members: The name, age, and salary variables are private, meaning they cannot be accessed directly from outside the class.
  • Public Methods: The getName, setName, getAge, setAge, getSalary, and setSalary methods are public, providing controlled access to the private members.
  • Data Hiding: The internal state of the Employee object is hidden, and only the necessary methods are exposed to interact with the object.

Abstraction

Definition

Abstraction is the concept of hiding the complex implementation details and showing only the essential features of the object. It helps in reducing programming complexity and effort.

Key Points

  • Simplification: Abstraction simplifies the design of complex systems by breaking them down into smaller, more manageable pieces.
  • Interfaces: In C++, abstraction can be achieved using abstract classes and interfaces.

Example

#include <iostream>
using namespace std;

// Abstract class
class Shape {
public:
    // Pure virtual function
    virtual void draw() = 0;
};

class Circle : public Shape {
public:
    void draw() override {
        cout << "Drawing Circle" << endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() override {
        cout << "Drawing Rectangle" << endl;
    }
};

int main() {
    Shape* shape1 = new Circle();
    Shape* shape2 = new Rectangle();

    shape1->draw();
    shape2->draw();

    delete shape1;
    delete shape2;

    return 0;
}

Explanation

  • Abstract Class: The Shape class is an abstract class with a pure virtual function draw().
  • Derived Classes: The Circle and Rectangle classes inherit from Shape and provide their own implementation of the draw() method.
  • Polymorphism: The Shape pointer can point to any derived class object, and the appropriate draw() method is called at runtime.

Exercises

Exercise 1: Encapsulation

Create a class BankAccount with private members accountNumber, accountHolderName, and balance. Provide public methods to get and set these values, ensuring that the balance cannot be set to a negative value.

Solution

#include <iostream>
using namespace std;

class BankAccount {
private:
    int accountNumber;
    string accountHolderName;
    double balance;

public:
    // Constructor
    BankAccount(int accNum, string accHolder, double bal) : accountNumber(accNum), accountHolderName(accHolder), balance(bal) {}

    // Getter for accountNumber
    int getAccountNumber() {
        return accountNumber;
    }

    // Setter for accountNumber
    void setAccountNumber(int accNum) {
        accountNumber = accNum;
    }

    // Getter for accountHolderName
    string getAccountHolderName() {
        return accountHolderName;
    }

    // Setter for accountHolderName
    void setAccountHolderName(string accHolder) {
        accountHolderName = accHolder;
    }

    // Getter for balance
    double getBalance() {
        return balance;
    }

    // Setter for balance
    void setBalance(double bal) {
        if (bal >= 0) {
            balance = bal;
        }
    }

    // Display account details
    void display() {
        cout << "Account Number: " << accountNumber << ", Account Holder: " << accountHolderName << ", Balance: $" << balance << endl;
    }
};

int main() {
    BankAccount acc(123456, "Alice", 1000.0);
    acc.display();

    // Modify account details using setters
    acc.setAccountHolderName("Bob");
    acc.setBalance(1500.0);
    acc.display();

    return 0;
}

Exercise 2: Abstraction

Create an abstract class Animal with a pure virtual function makeSound(). Create two derived classes Dog and Cat that implement the makeSound() function.

Solution

#include <iostream>
using namespace std;

// Abstract class
class Animal {
public:
    // Pure virtual function
    virtual void makeSound() = 0;
};

class Dog : public Animal {
public:
    void makeSound() override {
        cout << "Woof Woof" << endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        cout << "Meow Meow" << endl;
    }
};

int main() {
    Animal* animal1 = new Dog();
    Animal* animal2 = new Cat();

    animal1->makeSound();
    animal2->makeSound();

    delete animal1;
    delete animal2;

    return 0;
}

Conclusion

In this section, we covered the concepts of encapsulation and abstraction in C++. Encapsulation helps in bundling data and methods together while restricting access to the internal state of an object. Abstraction helps in hiding the complex implementation details and exposing only the essential features. These concepts are crucial for building robust and maintainable software. In the next module, we will delve into more advanced topics in C++ programming.

© Copyright 2024. All rights reserved