Encapsulation

From JholJhapata

Encapsulation is the process of wrapping the data and code under a single unit. It is the mechanism that binds together code and the data it manipulates. In a different way, encapsulation is a protective shield that prevents the data from being accessed by the code outside this shield.

Technically in encapsulation, the data in a class is hidden from other classes, so it is also known as data-hiding.

Why do we need Encapsulation

Encapsulation provides a way to protect data(Data-Hiding), Increases Flexibility, Re-usability and Testability.

  • Data-Hiding: The user will have no idea about the inner implementation of the class. It will not be visible to the user that how the class is stored values in the variables. He only knows that we are passing the values to accessors and variables are getting initialized to that value.
  • Increased Flexibility: We can make the variables of the class as read-only or write-only depending on our requirement. If we wish to make the variables as read-only then we have to only use Get Accessor in the code. If we wish to make the variables as write-only then we have to only use Set Accessor.
  • Reusability: Encapsulation also improves the re-usability and easy to change with new requirements.
  • Testing code is easy(Testability): Encapsulated code is easy to test for unit testing.

Implementation of Encapsulation

Encapsulation is implemented by using access specifiers, which defines the scope and visibility of a class member:

  • Public
  • Private
  • Protected
  • Internal
  • Protected internal

Public Access Specifier

Public access specifier allows all the class members declared under public will be available to everyone. The data members and member functions declared public can be accessed by other classes. The public members of a class can be accessed from anywhere in the program using the direct member access operator (.) with the object of that class.

Public Access Specifier Example

You will notice how we can access all the members of class "Rectangle" with the object in the "Main" function.

   class Rectangle
   {
       public double length { get; set; }
       public double width { get; set; }
       public double calculateArea()
       {
           return (length * width);
       }
   }
   class Process
   {
       static void Main(string[] args)
       {
           Rectangle _rectangle = new Rectangle();
           _rectangle.length = 4;
           _rectangle.width = 5;
           double val = _rectangle.calculateArea();
           Console.WriteLine(val.ToString());
       }
       
   }

Private Access Specifier

The private access specifiers hides/restricts its member variable and method from other/outside class and methods.

Private Access Specifier Example

You will notice below errors while accessing the members of class "Rectangle" with the object in the "Main" function. 'Rectangle.length' is inaccessible due to its protection level
'Rectangle.width' is inaccessible due to its protection level

   class Rectangle
   {
       private double length { get; set; }
       private double width { get; set; }
       public double calculateArea()
       {
           return (length * width);
       }
   }
   class Process
   {
       static void Main(string[] args)
       {
           Rectangle _rectangle = new Rectangle();
           _rectangle.length = 4;
           _rectangle.width = 5;
           double val = _rectangle.calculateArea();
           Console.WriteLine(val.ToString());
       }
   }


Protected Access Specifier

Protected members of a class can only be accessed within the class or in child/derived classes. It becomes very important while implementing inheritance.

Protected Access Specifier Example

You will notice below errors while accessing the members of class "Rectangle" with the object in the "Main" function. 'Rectangle.length' is inaccessible due to its protection level
'Rectangle.width' is inaccessible due to its protection level

   class Rectangle
   {
       protected double length { get; set; }
       protected double width { get; set; }
       public double calculateArea()
       {
           return (length * width);
       }
   }
   class Process
   {
       static void Main(string[] args)
       {
           Rectangle _rectangle = new Rectangle();
           _rectangle.length = 4;
           _rectangle.width = 5;
           double val = _rectangle.calculateArea();
           Console.WriteLine(val.ToString());
       }
   }

Now lets fix this by inheriting "Rectangle" in "Main" class.

   class Rectangle
   {
       protected double length { get; set; }
       protected double width { get; set; }
       public double calculateArea()
       {
           return (length * width);
       }
   }
   class Process : Rectangle
   {
       static void Main(string[] args)
       {
           Process _rectangle = new Process();
           _rectangle.length = 4;
           _rectangle.width = 5;
           double val = _rectangle.calculateArea();
           Console.WriteLine(val.ToString());
       }
   }

Internal Access Specifier

The internal members are accessible only within files in the same assembly (.dll). In other words internal access specifier hides its member variables and methods from other classes and objects, that is resides in other namespace.

Internal Access Specifier Example

You will notice how we can access all the members of class "Rectangle" with the object in the "Main" function.

   class Rectangle
   {
       internal double length { get; set; }
       internal double width { get; set; }
       public double calculateArea()
       {
           return (length * width);
       }
   }
   class Process
   {
       static void Main(string[] args)
       {
           Rectangle _rectangle = new Rectangle();
           _rectangle.length = 4;
           _rectangle.width = 5;
           double val = _rectangle.calculateArea();
           Console.WriteLine(val.ToString());
       }
   }

Protected Internal Access Specifier

The protected internal keyword combination is a member access modifier. A protected internal member is accessible from the current assembly or from types that are derived from the containing class.