41. Encapsulation#
When crafting software, managing complexity is essential. In the world of object-oriented programming, we often strive to design our classes to encapsulate complexity. Encapsulation is the practice of hiding the details of how objects work and exposing only what’s necessary. This principle forms the bedrock of robust, flexible, and maintainable code.
Encapsulation in C# refers to the bundling of data, represented by fields, and methods that act on that data, into a single unit such as a class. More than just a packaging mechanism, encapsulation also involves hiding the internal states and implementation details of an object and providing a clean, accessible way to interact with the object.
Encapsulation is often used synonymously with “information hiding”. At times and to some people, the two have meant different things. Today however, they are both often used to the idea of “hiding your private parts”.
Consider the following Car
class:
public class Car
{
private int speed;
public int GetSpeed()
=> speed;
public void Accelerate(int delta)
{
if (delta < 0)
delta = 0; // min
speed += delta;
}
public void Brake(int delta)
{
if (delta < 0)
delta = 0; // min
else if (delta > speed)
delta = speed; // max
speed -= delta;
}
}
In this class, the speed field is marked as private
, which means it can only be accessed directly within the Car
class. This is encapsulation in action: we’re hiding the speed
field and providing public
methods (Accelerate
, Brake
, and GetSpeed
) as the, so called, ‘interface’ to interact with it.
We say that we’ve ‘encapsulated’ or ‘hidden’ speed
.
Car car = new Car();
car.Accelerate(10);
car.Accelerate(-10);
Console.WriteLine(car.GetSpeed());
10
Car car = new Car();
car.Accelerate(5);
car.Brake(12);
car.Accelerate(2);
Console.WriteLine(car.GetSpeed());
2
By hiding the speed
field, we can ensure that the speed can never be set to an invalid state. We can ensure that acceleration and braking deltas must be positive, and that braking can’t exceed the existing speed. These constraints are enforced by the Accelerate
and Brake
methods, protecting the speed
field from inconsistent states.
Since the only way to update the speed
of a Car
object is through its public interface we ensure that the speed is always updated ‘consistently’.
Remember, when a member is private
it is not accessible from the outside.
Car car = new Car();
car.speed = 10;
(2,5): error CS0122: 'Car.speed' is inaccessible due to its protection level
Encapsulation, often used synonymously with “information hiding”, is a foundational concept in object-oriented programming. It simplifies the usage of our classes and objects, reduces the likelihood of bugs, and improves code maintainability. As you continue your journey with C#, understanding and applying encapsulation will be vital for keeping your programs alive over time.