Protected Access

Introduction

protected access modifier allows access within the same package and in subclasses (even in different packages).


Access Modifiers Overview

ModifierClassPackageSubclassWorld
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:

  1. Methods subclasses should override
  2. Fields subclasses need to access
  3. Helper methods for inheritance hierarchy
  4. Template patterns

Don’t use protected for:

  1. Public API (use public)
  2. Implementation details (use private)
  3. 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:

  1. Protected = package + subclasses
  2. Accessible in same package
  3. Accessible in subclasses (any package)
  4. Not accessible to unrelated classes (different package)
  5. More restrictive than public
  6. Less restrictive than default
  7. Used for inheritance
  8. Good for template methods
  9. Cannot use in interfaces (pre-Java 9)
  10. 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?