OOP Concepts: Encapsulation

Dated Sep 14, 2026; last modified on Mon, 14 Sep 2026

Keep an object’s data private and let the object control how that data is used. For example, the Account class should own its balance field, and only let clients modify it through deposit() and withdraw(). That way, Account can enforce rules, e.g., no negative balances, log transactions, etc.

I’ve commonly encountered code like:

class Foo
{
  public:
    Bar& get_bar() { return bar_; }
    void set_bar(Bar bar) { bar_ = bar; }

  private:
    Bar bar_ = new();
}

… where the public getter and setter make the private member effectively public. This comes from either cargoculting encapsulation, or intending to run some code around setting/getting bar_ but never getting to write that code.

As another example, do not:

public class ParkingLot
{
  public List<ParkingSpot> Spots = new();
}

… instead do:

public class ParkingLot
{
  private readonly List<ParkingSpot> _parkingSpots = new();

  public bool ParkVehicle(Vehicle vehicle)
  {
    var spot = FindAvailableSpot(vehicle);
    if (spot == null) return false;

    spot.Occupy(vehicle);
    return true;
  }

  public List<ParkingSpot> GetSpots() => new List<ParkingSpot>(_parkingSpots);

  private ParkingSpot? FindAvailableSpot(Vehicle vehicle)
  {
    return _parkingSpots.Where(spot => !spot.IsOccupied()).FirstOrDefault();
  }
}

Avoid GetSpots()’s copying by instead having:

public IReadOnlyList<ParkingSpot> GetSpots() => _parkingSpots;

… because IReadOnlyList supports indexing into the collection, but not modifying it.

  1. OOP Concepts | Hello Interview Low Level Design. www.hellointerview.com . Accessed Sep 14, 2026.