artiface/artiface/ ObjectEncapsulation


Encapsulation

Encapsulation is a concept in object oriented programming. Essentially it means bundling code and data so that the access to that data can be controlled through an interface.

As an example we shall use a simple class in Java.

public class MyClass {
  private int value;
  private String name;
  public MyClass(int _value, String _name) {
    this.value = _value;
    this.name = _name;
  }

  // The return values of these methods do not
  // give access 
  public int getValue() {
    // Primitive variables in Java are returned
    // by value
    return this.value; // returns by value
  }
  public String getName() {
    // returns by reference, but String objects
    // are immutable, so the caller cannot modify
    // the String name in a MyClass object even
    // though it is given a reference to that String.
    return this.name;
  }
}
public class App {
    public static void main(String[] args) throws Exception {
      MyClass object = new MyClass(42,"hello world");

      String name = object.getName();
      // not an error, but replaces the String returned by another one
      // the string returned is immutable
      name = "hello"; 

      int answer = object.getValue();
      // not an error, but doesn't affect the value in 'object'
      answer = 4; 

      // the following two lines are errors which cause the code not to compile
      /*
      object.name = "world"; // error: field name is not public
      object.value = 10; // error: field value is not public
      */

      System.out.println("The name is " + name + " and the answer is " + answer);
    }
}

Here, the only way to assign the fields name and value, is to specify them in the arguments to the constructor ( new MyClass(42,"hello world") ). The only way to access them is via the methods getName and getValue.

The point of encapsulation

As projects grow in size, it becomes harder and harder to reliably reason about the behaviour of the resulting programs. Reasoning about, and controlling, the complexity of a growing codebase is much of the point of modern software engineering techniques. By hiding data behind an interface which restricts how that data can be accessed and modified, we reduce the possibilities for how that data can be manipulated. This results in a greater capacity to reason about the resulting code, and decreases the possibilities for the data in an object to be corrupted from outside.

Encapsulation in non-object-oriented languages

Encapsulation can be implemented in languages which are not object oriented, although languages such as C++ and Java provide support at the language level. As an example of encapsulation in a non-OO language we can look to the lower level APIs in macOS, such as Core Foundation, where for example, strings are represented as CFString objects which, to the user of the API, appear as opaque pointers (a CFStringRef). Functions such as CFStringGetLength act on these opaque pointers but no details as to the internal representation of these objects is available to code outside of their implementation.