Introduction
protected access modifier allows access within the same package and in subclasses (even in different packages).
Access Modifiers Overview
| Modifier | Class | Package | Subclass | World |
|---|---|---|---|---|
| public | ✓ | ✓ | ✓ | ✓ |
| protected | ✓ | ✓ | ✓ | ✗ |
| default | ✓ | ✓ | ✗ | ✗ |
| private | ✓ | ✗ | ✗ | ✗ |
Basic Example
// Parent.java
package mypackage;
public class Parent {
protected int protectedVar = 10;
protected void protectedMethod() {
System.out.println("Protected method");
}
}
// Child.java (same package)
package mypackage;
public class Child extends Parent {
void display() {
System.out.println(protectedVar); // ✓ Accessible
protectedMethod(); // ✓ Accessible
}
}
// Main.java (same package)
package mypackage;
public class Main {
public static void main(String[] args) {
Parent p = new Parent();
System.out.println(p.protectedVar); // ✓ Accessible (same package)
p.protectedMethod(); // ✓ Accessible (same package)
}
}
Protected in Different Package
// Parent.java
package package1;
public class Parent {
protected int protectedVar = 10;
protected void protectedMethod() {
System.out.println("Protected method");
}
}
// Child.java (different package)
package package2;
import package1.Parent;
public class Child extends Parent {
void display() {
System.out.println(protectedVar); // ✓ Accessible (subclass)
protectedMethod(); // ✓ Accessible (subclass)
}
}
// Main.java (different package, not subclass)
package package2;
import package1.Parent;
public class Main {
public static void main(String[] args) {
Parent p = new Parent();
// System.out.println(p.protectedVar); // ✗ Not accessible
// p.protectedMethod(); // ✗ Not accessible
}
}
Simple Same Package Example
class Animal {
protected String name;
protected void eat() {
System.out.println(name + " is eating");
}
}
class Dog extends Animal {
void display() {
name = "Buddy"; // ✓ Accessible
eat(); // ✓ Accessible
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Animal();
animal.name = "Generic"; // ✓ Accessible (same package)
animal.eat(); // ✓ Accessible (same package)
Dog dog = new Dog();
dog.display();
}
}
Complete Example
class Person {
protected String name;
protected int age;
protected Person(String name, int age) {
this.name = name;
this.age = age;
}
protected void displayInfo() {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
}
}
class Student extends Person {
private int rollNo;
private double marks;
Student(String name, int age, int rollNo, double marks) {
super(name, age); // Access protected constructor
this.rollNo = rollNo;
this.marks = marks;
}
void display() {
// Access protected members
System.out.println("Student Name: " + name);
System.out.println("Student Age: " + age);
System.out.println("Roll No: " + rollNo);
System.out.println("Marks: " + marks);
// Call protected method
displayInfo();
}
}
public class Main {
public static void main(String[] args) {
Student student = new Student("John", 20, 101, 85.5);
student.display();
// Direct access (same package)
student.name = "Alice"; // ✓ Accessible
student.displayInfo(); // ✓ Accessible
}
}
Protected Constructor
class Parent {
protected Parent() {
System.out.println("Protected constructor");
}
}
class Child extends Parent {
Child() {
super(); // ✓ Can call protected constructor
System.out.println("Child constructor");
}
}
public class Main {
public static void main(String[] args) {
// Parent p = new Parent(); // Accessible if in same package
Child c = new Child();
}
}
Protected Fields
class BankAccount {
protected double balance;
protected String accountNumber;
protected void deposit(double amount) {
balance += amount;
}
}
class SavingsAccount extends BankAccount {
private double interestRate;
void addInterest() {
// Access protected field
double interest = balance * interestRate / 100;
deposit(interest); // Call protected method
}
void display() {
System.out.println("Account: " + accountNumber);
System.out.println("Balance: " + balance);
}
}
Access Through Reference
class Parent {
protected int value = 10;
}
class Child extends Parent {
void display() {
// Own inherited member
System.out.println(value); // ✓ OK
System.out.println(this.value); // ✓ OK
// Through Child reference
Child c = new Child();
System.out.println(c.value); // ✓ OK
// Through Parent reference (different package)
Parent p = new Parent();
// System.out.println(p.value); // ✗ Not OK (if different package)
}
}
Why Use Protected?
1. Allow Subclass Access:
class Shape {
protected String color;
protected void setColor(String color) {
this.color = color;
}
}
class Circle extends Shape {
void draw() {
setColor("Red"); // Access protected method
System.out.println("Drawing " + color + " circle");
}
}
2. Hide from Outside:
// Not accessible outside package (unless subclass)
protected void internalMethod() {
// Implementation details
}
3. Template Methods:
class Template {
protected void step1() { }
protected void step2() { }
protected void step3() { }
public final void execute() {
step1();
step2();
step3();
}
}
Real-World Example
class Employee {
protected String name;
protected double salary;
protected Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
protected double calculateBonus() {
return salary * 0.1; // 10% bonus
}
protected void displayInfo() {
System.out.println("Name: " + name);
System.out.println("Salary: " + salary);
}
}
class Manager extends Employee {
private String department;
Manager(String name, double salary, String department) {
super(name, salary);
this.department = department;
}
@Override
protected double calculateBonus() {
return salary * 0.2; // 20% bonus for managers
}
void showDetails() {
displayInfo(); // Call protected method
System.out.println("Department: " + department);
System.out.println("Bonus: " + calculateBonus());
}
}
class Developer extends Employee {
private String language;
Developer(String name, double salary, String language) {
super(name, salary);
this.language = language;
}
void showDetails() {
displayInfo(); // Call protected method
System.out.println("Language: " + language);
System.out.println("Bonus: " + calculateBonus());
}
}
public class Main {
public static void main(String[] args) {
Manager mgr = new Manager("John", 50000, "IT");
mgr.showDetails();
System.out.println();
Developer dev = new Developer("Alice", 40000, "Java");
dev.showDetails();
}
}
Protected vs Public vs Private
class Example {
public int publicVar; // Accessible everywhere
protected int protectedVar; // Package + subclasses
int defaultVar; // Package only
private int privateVar; // Class only
public void publicMethod() { }
protected void protectedMethod() { }
void defaultMethod() { }
private void privateMethod() { }
}
Design Guidelines
Use protected for:
- Methods subclasses should override
- Fields subclasses need to access
- Helper methods for inheritance hierarchy
- Template patterns
Don’t use protected for:
- Public API (use public)
- Implementation details (use private)
- Unrelated classes (won’t help)
Quick Reference
class Parent {
protected int x = 10; // Protected field
protected void method() { } // Protected method
protected Parent() { } // Protected constructor
}
// Same package
class SamePackage {
void test() {
Parent p = new Parent();
p.x = 20; // ✓ Accessible
p.method(); // ✓ Accessible
}
}
// Different package - subclass
class Child extends Parent {
void test() {
x = 20; // ✓ Accessible (inherited)
method(); // ✓ Accessible (inherited)
}
}
// Different package - not subclass
class Other {
void test() {
Parent p = new Parent();
// p.x = 20; // ✗ Not accessible
// p.method(); // ✗ Not accessible
}
}
Common Mistakes
Mistake 1: Assuming Public Access
// In different package
Parent p = new Parent();
// p.protectedMethod(); // ✗ Error (not subclass)
Mistake 2: Protected with Interfaces
// ✗ Interfaces cannot have protected methods
interface Wrong {
// protected void method(); // Error
}
Exam Tips
Remember:
- Protected = package + subclasses
- Accessible in same package
- Accessible in subclasses (any package)
- Not accessible to unrelated classes (different package)
- More restrictive than public
- Less restrictive than default
- Used for inheritance
- Good for template methods
- Cannot use in interfaces (pre-Java 9)
- Between public and private
Common Questions:
- What is protected access?
- Protected vs public?
- Protected vs private?
- Can subclass access protected members?
- Protected in same package?
- Protected in different package?
- When to use protected?
- Access modifiers comparison?