Access Modifiers
Access modifiers are the locks on your class. They decide which code may see or change each field and method — and they turn encapsulation from a promise into a rule.
On this page · 5 min · Beginner
On this page
- In simple words
- Learning objectives
- Explanation
- Syntax
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Beginner
- Updated
- Oct 28, 2026
Related tutorials
In simple words#
Rooms in a house: the living room is public, bedrooms are private, and some rooms are only for family (protected). Access modifiers decide who may enter which part of a class.
- public
- Anyone can use it.
- private
- Only this class.
- protected / internal
- Child classes / same project.
Learning objectives#
- Explain public, private, protected and internal
- Use #private fields and methods in JavaScript
- Choose the most restrictive modifier that works
- Know the JavaScript “_protected” convention
Explanation#
public: anyone can use it. private: only code inside the same class. protected: the class and its subclasses. internal (C#): any code in the same project (assembly).
C# also has protected internal (subclasses OR same project) and private protected (subclasses in the same project). You will rarely need them.
In C#, members are private by default and classes are internal by default.
JavaScript has only two real levels: public, and private with #. A # field or method is invisible outside the class — even to subclasses. There is no protected keyword; developers mark “internal use” members with an underscore (_department), but that is only a convention.
Start private, and open up only when there is a reason. Every public member is a promise you must keep when the class changes.
Syntax#
public class Employee
{
public string Name { get; } // anyone
protected string Department { get; } // this class + subclasses
internal int BadgeNumber { get; } // same project
private decimal _salary; // this class only
private decimal TaxRate() => _salary > 50000 ? 0.3m : 0.1m;
}
Code example: Who can see the salary?#
class Employee {
#salary; // private: only Employee
_department; // "protected" by convention only
constructor(name, salary, department) {
this.name = name; // public
this.#salary = salary;
this._department = department;
}
get annualSalary() {
return this.#salary * 12;
}
#taxPercent() { // private method
return this.#salary > 50000 ? 30 : 10;
}
netMonthly() {
return (this.#salary * (100 - this.#taxPercent())) / 100;
}
}
class Manager extends Employee {
describe() {
// return this.#salary; // SyntaxError: #salary is private to Employee
return `${this.name} manages ${this._department}`;
}
}
const m = new Manager('Ravi', 80000, 'Sales');
console.log(m.describe());
console.log(m.annualSalary);
console.log(m.netMonthly());
console.log(Object.keys(m));
console.log(m.salary);
Ravi manages Sales 960000 56000 [ '_department', 'name' ] undefined
Step-by-step explanation#
- #salary and #taxPercent() exist only inside Employee. Even Manager cannot read them.
- Public members (name, annualSalary, netMonthly) form the class’s official interface.
- _department is public in reality; the underscore only signals “meant for subclasses”.
- Object.keys lists only public fields — the private #salary does not appear.
- m.salary is undefined: there is no public salary property at all.
Real-world use case#
A payroll library exposes only CalculatePayslip() as public. Tax tables and rounding helpers are private, so the team can change them without breaking any application that uses the library.
Common mistakes#
Public members are hard to change later because other code depends on them. Default to private.
In JavaScript, _department can still be read and changed by anyone. Use # for real privacy.
Protected fields let every subclass break the base class’s rules. Prefer protected methods over protected fields.
Best practices#
- Use the most restrictive modifier that works
- Keep fields private; expose properties or methods
- Treat public members as a contract
- Use internal in C# libraries for helpers other projects should not see
Remember this#
public = everyone. private = this class. protected = + children. internal = same project.
JavaScript: # is truly private; _ is just a hint.
Start private, open up only when needed.
Practice exercise#
Your task: Create a PasswordVault class that stores passwords in a private #store Map. Expose save(site, password) and has(site), but no way to read a password back.
Need a hint?
Show solution
class PasswordVault {
#store = new Map();
save(site, password) { this.#store.set(site, password); }
has(site) { return this.#store.has(site); }
}
const vault = new PasswordVault();
vault.save('mail', 's3cret');
console.log(vault.has('mail')); // true
console.log(vault.store); // undefined
Mini quiz#
Which C# modifier lets subclasses use a member but hides it from other code?
Want more? Practise all OOP Concepts MCQs · OOP Concepts interview questions
My notes#
Saved in this browser.