🌐 What are Access Modifiers?
Access modifiers control where a class, method, or field can be accessed from.
Java provides 4 levels of access:
| Modifier | Access Scope |
|---|---|
| public | Accessible from everywhere (inside the class, package, subclasses, and outside packages) |
| protected | Accessible within the same package and also in subclasses, even if they are in different packages |
| default (no modifier) | Accessible within the same package only |
| private | Accessible only within the same class |
🔎 Detailed Explanation
1️⃣ public
- Most open access.
- Can be accessed from anywhere — inside the same class, other classes in the same package, and even classes in different packages.
- Suitable for APIs, public methods, constants.
public class Animal {
public void eat() {
System.out.println("Animal eating");
}
}
✅ This eat() method can be called from any class, in any package.
2️⃣ protected
- Accessible within:
- Same package (like
default). - Subclasses, even if the subclass is in a different package.
- Same package (like
- Suitable for:
- Methods intended for inheritance (but not for general use).
class Animal {
protected void makeSound() {
System.out.println("Animal sound");
}
}
✅ A Dog subclass (even in a different package) can call makeSound(), but unrelated classes cannot.
3️⃣ default (package-private)
- No keyword means default access.
- Accessible only within the same package.
- Suitable for:
- Package-internal classes and helpers.
class Animal {
void sleep() {
System.out.println("Animal sleeping");
}
}
✅ This sleep() method can only be called from other classes in the same package.
4️⃣ private
- Most restrictive.
- Accessible only within the same class.
- Suitable for:
- Internal fields, helper methods, or private logic you want to hide from others.
class Animal {
private void breathe() {
System.out.println("Animal breathing");
}
}
✅ No class outside Animal can access breathe(), not even subclasses.
📊 Quick Summary Table
| Modifier | Same Class | Same Package | Subclass (Different Package) | Other Packages |
|---|---|---|---|---|
| public | ✔️ | ✔️ | ✔️ | ✔️ |
| protected | ✔️ | ✔️ | ✔️ | ❌ |
| default | ✔️ | ✔️ | ❌ | ❌ |
| private | ✔️ | ❌ | ❌ | ❌ |
🔥 Important Rules for Interviews
✅ Classes (top-level) can only be public or default — they cannot be private or protected.
✅ Inside a class (fields, methods, inner classes), you can use all 4 (public, protected, default, private).
✅ protected = package + inheritance — this is often misunderstood!
✅ default = package-private — this is the actual technical name.
📚 Example for All Modifiers in One File
public class Animal {
public String name; // Accessible everywhere
protected int age; // Accessible in package + subclasses
String type; // Package-private (default)
private String secret; // Accessible only within Animal class
public void eat() { System.out.println("Eating"); } // Public
protected void makeSound() { System.out.println("Sound"); } // Protected
void sleep() { System.out.println("Sleeping"); } // Default
private void breathe() { System.out.println("Breathing"); } // Private
}
🎯 Final Pro Tip for Interviews
✅ If you need to explain best practices, say:
public: for public APIs, library methods.protected: for methods meant for extension (subclasses).default: for package-internal helpers.private: for strict internal logic (encapsulation).
✅ Inheritance trick: protected is more open than default — protected works even across packages, but only for subclasses.