Access Modifiers
Access Modifiers
Java has four access levels that control visibility of classes, fields, and methods. Understanding them is essential for proper encapsulation.
The Four Access Levels
| 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 |
Private
private members are only accessible within the declaring class. This is the most restrictive level and the default choice for fields:
class BankAccount {
private double balance;
public double getBalance() { return balance; }
public void deposit(double amount) {
if (amount > 0) balance += amount;
}
}
By making balance private, we force all access through methods that can validate input. This is the core of encapsulation.
Package-Private (Default)
When you write no modifier, the member is visible to all classes in the same package. This is called package-private or default access:
class Helper {
int count = 0; // package-private field
void increment() { count++; } // package-private method
}
Use this when classes within the same package need to collaborate closely, but outsiders should not depend on the implementation.
Protected
protected is like package-private but also grants access to subclasses in other packages:
class Shape {
protected String color;
protected void describe() {
System.out.println("A " + color + " shape");
}
}
class Circle extends Shape {
Circle(String color) {
this.color = color; // OK — subclass access
}
}
Public
public members are accessible from anywhere. Use this for the API your class exposes to the outside world.
Best Practices
- Start with
private— only widen access when you have a clear reason. - Expose behavior, not data — provide methods instead of public fields.
- Use
protectedsparingly — it couples subclasses to implementation details. - Prefer package-private for internal helpers — they can change without breaking external code.
Your Task
-
Create a class
Userwith:- A
private String nameandprivate String emailfield - A
publicconstructor taking both values - A
public String getName()getter - A
public String getEmail()getter - A
private String maskEmail()method that returns the email with everything before@replaced by"***"(e.g."alice@example.com"→"***@example.com") - A
public String getPublicProfile()that returnsname + " <" + maskEmail() + ">"
- A
-
Create a class
Adminthat extendsUserwith:- A
protected String rolefield - A constructor taking name, email, and role
- A
public String getPublicProfile()override that returnsname + " [" + role + "] <" + maskEmail() + ">"— but sincemaskEmail()is private, you must callgetEmail()and do the masking yourself
- A
-
In
main, create aUser("Alice", "alice@example.com")and anAdmin("Bob", "bob@corp.io", "SuperAdmin"). Print each one's public profile.