Access Modifiers

Lesson 0007 — 25 min read

Access modifiers control who can see and touch a class's members. They are the mechanisms that enforce encapsulation.

Purpose

The Four Levels

1. Public

Accessible from anywhere — same class, subclasses, same package, other packages.

class Employee {
public:
    string name;
    void displayName() {
        cout << "Employee Name: " << name << endl;
    }
};

int main() {
    Employee emp;
    emp.name = "Alice";
    emp.displayName();
}
class Employee {
    public String name;
    public void displayName() {
        System.out.println("Employee Name: " + name);
    }
}

public class Main {
    public static void main(String[] args) {
        Employee emp = new Employee();
        emp.name = "Alice";
        emp.displayName();
    }
}
class Employee:
    def __init__(self):
        self.name = None  # public

    def displayName(self):
        print("Employee Name:", self.name)

emp = Employee()
emp.name = "Alice"
emp.displayName()

Best for: APIs, interfaces, methods that need universal availability.

2. Private

Accessible only within the declaring class. Not visible to subclasses or external code.

class BankAccount {
private:
    double balance;

public:
    double getBalance() { return balance; }

    void deposit(double amount) {
        if (amount > 0) balance += amount;
    }
};

int main() {
    BankAccount acnt;
    // acnt.balance;    // Error! Private
    cout << acnt.getBalance();  // OK
}
class BankAccount {
    private double balance;

    public double getBalance() { return balance; }

    public void deposit(double amount) {
        if (amount > 0) balance += amount;
    }
}

public class Main {
    public static void main(String[] args) {
        BankAccount acnt = new BankAccount();
        // acnt.balance;    // Error! Private
        System.out.println(acnt.getBalance());
    }
}
class BankAccount:
    def __init__(self):
        self.__balance = 0  # name-mangled

    def getBalance(self): return self.__balance

    def deposit(self, amount):
        if amount > 0: self.__balance += amount

acnt = BankAccount()
# acnt.__balance          # AttributeError
print(acnt.getBalance())  # OK

Best for: sensitive data that needs controlled access via getters/setters.

3. Protected

Accessible within the same class + subclasses. In Java, also accessible within the same package.

class Vehicle {
protected:
    string type;

    void displayType() {
        cout << "Vehicle Type: " << type << endl;
    }
};

class Car : public Vehicle {
public:
    Car() { this->type = "Car"; }  // OK
};
class Vehicle {
    protected String type;

    protected void displayType() {
        System.out.println("Vehicle Type: " + type);
    }
}

class Car extends Vehicle {
    public Car() { this.type = "Car"; }  // OK
}
class Vehicle:
    def __init__(self):
        self._type = None  # convention, not enforced

    def _displayType(self):
        print("Vehicle Type:", self._type)

class Car(Vehicle):
    def __init__(self):
        super().__init__()
        self._type = "Car"  # OK

Best for: providing subclass access while hiding from unrelated classes.

4. Default (No Modifier)

In C++, default is private. Class members without a specifier are private.

In Java, default is package-private. Accessible within the same package only.

In Python, everything is public by default. Access modifiers are conventions, not enforced by the language.

class PackageDemo {
    void showMessage() { }  // private by default
};
class PackageDemo {
    void showMessage() {
        System.out.println("Same package access.");
    }
}

public class Main {
    public static void main(String[] args) {
        PackageDemo demo = new PackageDemo();
        demo.showMessage();  // OK — same package
    }
}
class PackageDemo:
    def showMessage(self):
        print("Everything is public in Python.")

demo = PackageDemo()
demo.showMessage()  # always accessible

Comparison Tables

Java

Modifier Class Package Subclass World
Public Yes Yes Yes Yes
Protected Yes Yes Yes No
Default Yes Yes No No
Private Yes No No No

C++

Modifier Class Subclass Outside
Public Yes Yes Yes
Protected Yes Yes No
Private Yes No No

Python

Convention Syntax Enforced?
Public name No
Protected _name Convention only
Private __name Name mangling (bypassable)

In Java: Given protected int x in class A, which of these can access it?

Code trace: Does this compile in Java?

package p1;
class A { int x = 5; }

package p2;
import p1.A;
class B extends A {
    void show() { System.out.println(x); }
}

Notes

Access Modifiers :-

Access modifier ⇒ keyword controlling visibility of class members

Purpose ⇒ enforce encapsulation ; controlled access ; modularity

Four Levels :-

a) Public ⇒ accessible everywhere (class, package, subclass, world)

b) Private ⇒ accessible only within the declaring class

c) Protected ⇒ accessible within same class, subclasses, and same package (Java)

d) Default ⇒ package-private in Java ; private in C++ ; public by convention in Python

Language Summary :-

a) Java ⇒ 4 levels (public, protected, default, private) ; enforced at compile time

b) C++ ⇒ 3 levels (public, protected, private) ; default is private

c) Python ⇒ 3 conventions (public, _protected, __private) ; name mangling

Primary source: Oracle Java Tutorials — Controlling Access. Ask me anything that's unclear.

← Prev: Encapsulation Next: Inheritance →

Questions? Ask your agent — you can follow up on any concept, quiz answer, or how this applies to a specific coding problem. Review the Java glossary or syntax quick reference for a compressed overview.