Skip to content

Encapsulation binds together the code and data in a single unit of work (a class) and acts as a defensive shield that doesn’t allow the external code to access this data directly.

Notifications You must be signed in to change notification settings

lana-20/oop-encapsulation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 

Repository files navigation

Encapsulation

Encapsulation is one of the core concepts of Object Oriented Programming (OOP). Mainly, encapsulation binds together the code and data in a single unit of work (a class) and acts as a defensive shield that doesn’t allow the external code to access this data directly. It is the technique of hiding the object state from the outer world and exposing a set of public methods for accessing this state. When each object keeps its state private inside a class, encapsulation is achieved. This is why encapsulation is also known as the data-hiding mechanism.

The code that takes advantage of encapsulation is:

  • loosely coupled (eg., I can change the names of the class variables without breaking the client code)
  • reusable
  • secure (the client is not aware of how data is manipulated inside the class)
  • easy to test (it’s easier to test methods than fields)

In Java, encapsulation can be achieved via the access modifiers/specifiers, public, private, and protected.

Everything is public by default.

In Python:

  • To make fields/variables and methods protected, prefix them with a single underscore '_'. Eg., _field or def _method().
  • To make fields/variables and methods private, prefix them with a dunder '__'. Eg., __field or def __method().

Commonly, when on object manages its own state, its state is declared via private variables and is accessed and/or modified via public methods. For example, a Cat class can have its own state represented by fields, such as mood, hungry, and energy. While the code external to the Cat class cannot modify any of these fields directly, it can call public methods, such as play(), feed() and sleep() that modify the Cat state internally. The Cat class may also have private methods that are not accessible outside the class, such as meow().

This is encapsulation.

Java code sample:

public class Cat {

  private int mood = 50;
  private int hungry = 50;
  private int energy = 50;

  public void sleep() {
    System.out.println(“Sleep …”);
    energy ++;
    hungry ++;
  }

  public void play() {
    System.out.println(“Play …”);
    mood ++;
    energy --;
    meow();
  }

  public void feed() {
    System.out.println(“Feed …”);
    hungry --;
    mood ++;
    meow();
  }

  private void meow() {
    System.out.println(“Meow …”);
  }

  public int getMood() {
    return mood;
  }

  public int getHungry() {
    return hungry;
  }

  public int getEnergy() {
    return energy;
  }
}

The only way to modify the state is via the public methods, play(), feed(), and sleep().

public static void main(String[] args) {

  Cat cat = new Cat();

  cat.feed();
  cat.play();
  cat.feed();
  cat.sleep();

  System.out.println(“Energy: ” + cat.getEnergy());
  System.out.println(“Mood: ” + cat.getMood());
  System.out.println(“Hungry: ” + cat.getHungry());
}

The output is as follows:

Feed …Meow!Play …Meow!Feed …Meow!Sleep …

Energy: 50
Mood: 53
Hungry: 49

Here's the Python equivalent of the Java code, using Python property decorators to demonstrate encapsulation in Object Oriented Programming:

class Cat:
    def __init__(self):
        self._mood = 50
        self._hungry = 50
        self._energy = 50

    def sleep(self):
        print("Sleep…")
        self._energy += 1
        self._hungry += 1

    def play(self):
        print("Play…")
        self._mood += 1
        self._energy -= 1
        self._meow()

    def feed(self):
        print("Feed…")
        self._hungry -= 1
        self._mood += 1
        self._meow()

    def _meow(self):
        print("Meow…")

    @property
    def mood(self):
        return self._mood

    @property
    def hungry(self):
        return self._hungry

    @property
    def energy(self):
        return self._energy

if __name__ == "__main__":
    cat = Cat()

    cat.feed()
    cat.play()
    cat.feed()
    cat.sleep()

    print("Energy:", cat.energy)
    print("Mood:", cat.mood)
    print("Hungry:", cat.hungry)

The output is as follows:

Feed…
Meow…
Play…
Meow…
Feed…
Meow…
Sleep…
Energy: 51
Mood: 52
Hungry: 52

In this implementation, the mood, hungry, and energy fields are declared as protected using the leading underscore notation. The get_mood(), get_hungry(), and get_energy() methods are replaced with Python property getters (declared using the @property decorator).

This way, the internal state of the Cat object can be accessed using the properties (eg., cat.energy), but the underlying fields cannot be directly modified.

About

Encapsulation binds together the code and data in a single unit of work (a class) and acts as a defensive shield that doesn’t allow the external code to access this data directly.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published