Intermediate · Classes and objects · topic 16 of 43 · 30 min
Access modifiers, static members and encapsulation
Explanation
Encapsulation: protect the data
Encapsulation is one of the main ideas of OOP. An object hides its data and exposes only the actions that keep it valid. A bank account should never have a negative balance by accident, so the balance is private and the only way to change it is Deposit or Withdraw, which check the rules.
Access modifiers
| Modifier | Who can use the member |
|---|---|
| public | Any code, anywhere |
| private | Only code inside the same class (the default for class members) |
| protected | The same class and classes that inherit from it (module 5) |
| internal | Any code in the same project / assembly (the default for top-level classes) |
| protected internal | The same project, OR derived classes anywhere |
| private protected | Derived classes that are also in the same project |
An assembly is the .dll your project builds. internal is useful for helper classes that other projects should not depend on.
public class BankAccount
{
private decimal _balance; // hidden
public string Owner { get; }
public decimal Balance => _balance; // read-only view
public BankAccount(string owner) => Owner = owner;
public void Deposit(decimal amount)
{
if (amount <= 0) throw new ArgumentException("Amount must be positive");
_balance += amount;
}
public bool TryWithdraw(decimal amount)
{
if (amount <= 0 || amount > _balance) return false;
_balance -= amount;
return true;
}
}static members: shared by the whole class
Normally each object has its own fields. A static field belongs to the class itself, so there is only one copy, shared by all objects. A static method belongs to the class too, so you call it on the class name, without creating an object. Math.Max and Console.WriteLine are static methods.
var t1 = new Ticket("Asha");
var t2 = new Ticket("Ravi");
Console.WriteLine($"{t1.No} {t2.No}"); // 1001 1002
Console.WriteLine(Ticket.IssuedSoFar); // 2
class Ticket
{
private static int _nextNo = 1001; // one counter for all tickets
public int No { get; }
public string Passenger { get; }
public Ticket(string passenger)
{
Passenger = passenger;
No = _nextNo++; // use, then increase
}
public static int IssuedSoFar => _nextNo - 1001;
}static classes
Console.WriteLine(Gst.Add(1000m)); // 1180.00
public static class Gst
{
public const decimal StandardRate = 0.18m;
public static decimal Add(decimal amount, decimal rate = StandardRate) => amount + amount * rate;
}const, readonly and static readonly
| Keyword | Set when? | Example |
|---|---|---|
| const | At compile time; must be a literal value | const int MaxSeats = 72; |
| readonly field | In its declaration or the constructor; then fixed for that object | private readonly string _accountNo; |
| static readonly | Once for the whole class, when the program starts using it | static readonly DateTime Started = DateTime.Now; |
Common mistakes and fixes
- Making everything public "to make it work": you lose the protection. Start with private and open up only what callers truly need.
- Forgetting that members are private by default: void Deposit() inside a class cannot be called from outside. Add public.
- Using a static field for per-user data like the "current user": every object and every request shares it. Use an instance field instead.
- Trying to new a static class: error. Call its members on the class name.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Access modifiers, static members and encapsulation · 1/7
In this lesson you will protect your objects with encapsulation.
Prefer a video by a teacher? Find free videos on “C# access modifiers static members encapsulation explained” on YouTube ↗
In real life: A metro smart card
A metro card stores a balance. Riders can recharge it and the gate deducts fares, but no app or person can set the balance directly. A static fare table is shared by every card.
var card = new MetroCard("MC-7781");
card.Recharge(200m);
Console.WriteLine(card.TryTapOut(stations: 6) ? $"Paid. Left: {card.Balance}" : "Low balance");
public class MetroCard
{
private decimal _balance;
public string CardNo { get; }
public decimal Balance => _balance;
public MetroCard(string cardNo) => CardNo = cardNo;
public void Recharge(decimal amount)
{
if (amount < 50m) throw new ArgumentException("Minimum recharge is 50");
_balance += amount;
}
public bool TryTapOut(int stations)
{
decimal fare = Fare(stations);
if (fare > _balance) return false;
_balance -= fare;
return true;
}
public static decimal Fare(int stations) => stations switch
{
<= 2 => 10m,
<= 5 => 20m,
<= 12 => 30m,
_ => 40m
};
}Practice (0/4 done)
What is the default access level of a method declared in a class without a modifier?
What does this print? var a = new Box(); var b = new Box(); var c = new Box(); Console.WriteLine(Box.Count); class Box { public static int Count; public Box() { Count++; } }
Why does a static method fail when it reads an instance field?
Design a class WalletAccount for a payments app. The balance must be private. Add AddMoney(decimal), TryPay(decimal amount, string to) that fails if the balance is too low, and a read-only Balance property. Add a static field that counts how many wallets were created, with a static property to read it.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Structs, value types and reference typesClasses and objects · same module
- Classes and objects: data plus behaviourC++ Programming (modern C++ and DSA) · Classes, constructors and RAII
- Encapsulation: private fields, getters and settersJava Programming (Core to Spring Boot) · Classes and objects
- ClassesJavaScript Programming (language in depth) · Scope, this, prototypes and classes
- static members and finalJava Programming (Core to Spring Boot) · Classes and objects
- Classes and objectsJava Programming (Core to Spring Boot) · Classes and objects
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What is encapsulation?
Answer: Hiding an object's data and allowing changes only through controlled members
Encapsulation protects an object's data and rules.
Who can access an internal class?
Answer: Any code in the same assembly (project)
internal means visible inside the same assembly.
How do you call a static method Fare on class MetroCard?
Answer: MetroCard.Fare(3)
Static members are reached through the class name.
Which can be set only in its declaration or the constructor?
Answer: a readonly field
readonly fields become fixed once construction finishes.
Can you write new Math()?
Answer: No, Math is a static class
Static classes cannot be instantiated.
A static member variable is…Related
Answer: shared by the whole class, one copy in total
Static members belong to the class, not to individual objects.
What is encapsulation?Related
Answer: Hiding data and exposing behaviour through methods that enforce rules
Objects protect their own state.
What makes a class field private?Related
How do you usually call a static method?Related
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Classes and objects” before its exam: Structs, value types and reference types.
- Module 4 exam: Classes and objects · 13 questions · 20 min, without help. 4 topics of this module still to finish first.
- Then the next module, Inheritance, interfaces and records. 43 topics left in the course before the final exam.