CLOSE

What is Encapsulation (Data Hiding)?

Encapsulation is one of the four fundamental principles of object-oriented programming (OOP). It refers to the bundling of data (attributes or properties) and methods (functions or procedures) that operate on that data into a single unit, called a class and restricting direct access to some of the object's components. The primary goal of encapsulation is to hide the internal state of an object from the outside world and to provide controlled access to that state through a well-defined interface.

Why Encapsulation?

Encapsulation offers several benefits:

  1. Data Hiding: Encapsulation allows the internal details of an object to be hidden from other parts of the program. This prevents unauthorized access to sensitive data and protects the integrity of the object's state.
  2. Abstraction: By exposing only the necessary information and functionality through a public interface, encapsulation abstracts away the implementation details of an object. This simplifies the complexity of interacting with the object and promotes a clear separation of concerns.
  3. Modularity: Encapsulation promotes modular design by encapsulating related data and behavior into cohesive units (classes). This makes the codebase easier to understand, maintain, and reuse.

Access Specifiers | Access Modifiers

Access Specifiers: C++ provides three access specifiers—public, private, and protected—to control the visibility of class members:

  1. public: Members declared as public are accessible from outside the class. They form the public interface of the class.
  2. private: Members declared as private are accessible only within the class itself. They are hidden from the outside world. If we don't specify any access modifiers by default it is private.
  3. protected: Members declared as protected are accessible within the class and its derived classes.

Access Modifiers Table:

Access ModifierAccessible Within ClassAccessible in Derived ClassAccessible Outside Class
private✅ Yes❌ No❌ No
protected✅ Yes✅ Yes❌ No
public✅ Yes✅ Yes✅ Yes

Example:

class MyClass {
private:
    int a;       // Only accessible inside MyClass

protected:
    int b;       // Accessible in MyClass and derived classes

public:
    int c;       // Accessible from anywhere
};

Purpose of Access Modifiers:

In object-oriented programming, the access modifiers play a key role and serve the following purposes:

  • Encapsulation: Ensure sensitive data and methods are protected from unintended access.
  • Controlled Access: Allows programmers to specify which parts of the program can interact with certain components.
  • Modularity and Security: Helps in maintaining the integrity of data by restricting unwanted modifications.

Mutators(Setters) and Accessors(Getters):

Mutators and accessors are specialized methods used to manipulate and retrieve the private member variables of a class, respectively.

They basically provide controlled access to private variables.

  • Mutators (Setters): Mutators are member functions that allow us to modify the values of private member variables. They typically follow the naming convention of setVariableName, where VariableName is the name of the member variable being modified.
class Car {
private:
    int speed; // Private member variable

public:
    void setSpeed(int s) { // Mutator (Setter)
        if (s >= 0) {
            speed = s;
        }
    }
};
  • Accessors (Getters): Accessors are member functions that allow us to retrieve the values of private member variables. They provide read-only access to the internal state of an object. Accessors typically follow the naming convention of getVariableName or simply variableName.
class Car {
private:
    int speed; // Private member variable

public:
    int getSpeed() const { // Accessor (Getter)
        return speed;
    }
};

Implementing Encapsulation in C++

In C++, encapsulation is achieved through the use of access specifiers and member functions:

  • Member Functions: Member functions (or methods) are used to manipulate the data members of a class. They provide controlled access to the internal state of objects and enforce encapsulation by encapsulating the logic for accessing and modifying the data.

Example: Encapsulation in C++

#include <iostream>

class Car {
private:
    std::string make;   // Private data members
    std::string model;
    int year;

public:
    // Public member functions to set and get the values of private data members
    void setMake(std::string make) {
        this->make = make;
    }

    std::string getMake() const {
        return make;
    }

    void setModel(std::string model) {
        this->model = model;
    }

    std::string getModel() const {
        return model;
    }

    void setYear(int year) {
        this->year = year;
    }

    int getYear() const {
        return year;
    }
};

int main() {
    Car car;
    car.setMake("Toyota");
    car.setModel("Camry");
    car.setYear(2020);

    std::cout << "Make: " << car.getMake() << std::endl;
    std::cout << "Model: " << car.getModel() << std::endl;
    std::cout << "Year: " << car.getYear() << std::endl;

    return 0;
}

In this example, the Car class encapsulates the data members make, model, and year, along with getter and setter methods to access and modify these members. The data members are declared as private, while the getter and setter methods are declared as public, enforcing encapsulation and controlled access to the internal state of Car objects.

Encapsulation vs Abstraction

EncapsulationAbstraction
Hides the internal stateHides complexity using simplified APIs
Achieved using access modifiersAchieved via abstract classes/interfaces
Focuses on howFocuses on what

Encapsulation is the mechanism that enforces abstraction.