Encapsulation

Keep the data private and let the outside world change it only through methods that enforce the rules.

Time O(1)Space O(1)Code C++, Python and C#
Watch it animatedStep through it, with the running line highlighted. Free with an account.

The idea

If any code could write to balance, any code could break it. Making the field private means every change goes through Withdraw, so the rule "never overdraw" lives in exactly one place.

Code

class Account {
    double balance_ = 500;                 // hidden from outside
public:
    double balance() const { return balance_; }   // read-only view
    void withdraw(double amount) {
        if (amount <= 0 || amount > balance_)
            throw invalid_argument("Invalid amount");
        balance_ -= amount;
    }
};
class Account:
    def __init__(self):
        self._balance = 500  # "private" by convention

    @property
    def balance(self) -> float:  # read-only view
        return self._balance

    def withdraw(self, amount: float) -> None:
        if amount <= 0 or amount > self._balance:
            raise ValueError("Invalid amount")
        self._balance -= amount
class Account {
    private decimal balance = 500;        // hidden from outside
    public decimal Balance => balance;    // read-only view
    public void Withdraw(decimal amount) {
        if (amount <= 0 || amount > balance)
            throw new InvalidOperationException("Invalid amount");
        balance -= amount;
    }
}

Tips

In the .NET library

Auto-properties do this in one line: public decimal Balance { get; private set; }. Use init instead of set for values that are fixed after construction.