What is the difference between default and protected access in Java?

Both default (no access modifier) and protected access modifiers in Java deal with visibility and accessibility, but they differ in how they handle access from subclasses. Here's a breakdown:

Default (No Access Modifier):

  • Visibility: Package-private. Members (variables, methods, or classes) with default access are only accessible by other classes within the same package. Classes outside the package cannot access them, even if they are subclasses.

Protected:

  • Visibility: Accessible within the same package and by subclasses, even if those subclasses are in a different package.

Key Differences Summarized :

Feature Default (No Modifier) Protected
Same Package Accessible Accessible
Different Package Not Accessible Accessible by subclasses
Subclasses Not Accessible (if in a different package) Accessible (even if in a different package)
Example :
// In package 'mypackage':

class MyClass {
    int defaultVariable = 10;       // Default access
    protected int protectedVariable = 20; // Protected access

    void defaultMethod() { }          // Default access
    protected void protectedMethod() { } // Protected access
}

// In package 'anotherpackage':

import mypackage.MyClass;

class MySubclass extends MyClass { // MySubclass is in a different package
    public void myMethod() {
        // Accessing members of MyClass from a subclass in a different package:
        // System.out.println(defaultVariable); // Compile-time error: defaultVariable is not accessible
        System.out.println(protectedVariable); // OK: protectedVariable is accessible by subclasses
        // defaultMethod(); // Compile-time error: defaultMethod is not accessible
        protectedMethod(); // OK: protectedMethod is accessible by subclasses
    }
}

class AnotherClass { // AnotherClass is in a different package (not a subclass)
    public void anotherMethod() {
        MyClass obj = new MyClass();
        // Accessing members of MyClass from a class in a different package (not a subclass):
        // System.out.println(obj.defaultVariable); // Compile-time error: defaultVariable is not accessible
        // System.out.println(obj.protectedVariable); // Compile-time error: protectedVariable is not accessible (unless AnotherClass is also a subclass)
        // obj.defaultMethod(); // Compile-time error: defaultMethod is not accessible
        // obj.protectedMethod(); // Compile-time error: protectedMethod is not accessible (unless AnotherClass is also a subclass)
    }
}?

 

When to Use Which?

  • Default: Use default access when you want to restrict the visibility of a class member to only within the same package. This is a good choice for implementation details that you don't want other packages to depend on.
  • Protected: Use protected access when you want to allow subclasses (even in different packages) to access and potentially override a member, while still restricting access from unrelated classes in other packages. This is commonly used in inheritance hierarchies where you want to provide certain functionality to subclasses but not to the outside world.