javaaccess-modifiers

Accessing a protected field of a different-package class within a class through an object of another class extending the one containing the field


I just wanted to ask a question about access modifiers in Java. I already searched for a similar question without any luck. I have the following class: `

package first.second; 
public class Powers {
    public int ninth = 512;
    private int tenth = 1024;
    protected int eleventh = 2048;
    int twelfth = 4096;
    
    public static void main(String args[]){
    
        Powers p = new Powers();
        System.out.println(p.tenth);
        System.out.println(p.ninth);
        System.out.println(p.eleventh);
        System.out.println(p.twelfth);
    
    }
}

Then, I have the following two classes located in the same package between them but in a different one with respect to class Powers:

package first; 
import first.second.Powers;

public class SuperPowers extends Powers {
    
    public void printPowers () {
    
        System.out.println(this.eleventh); // accessing directly to the protected field
        SuperPowers sp = new SuperPowers();
        System.out.println(sp.eleventh); // accessing it through a SuperPowers object
        // System.out.println(twelfth); // ERROR
    
    }
}

package first;
import first.second.Powers;

public class TestPowers {

    public static void main(String[] args) {
    
        Powers p = new Powers();
        System.out.println(p.ninth);
        //System.out.println(p.tenth); // ERROR
        //System.out.println(p.eleventh); // ERROR
        //System.out.println(p.twelfth); // ERROR
    
        SuperPowers sp = new SuperPowers();
        sp.printPowers(); // We can access it from SuperPowers, which extends Powers!
        // System.out.println(sp.eleventh); // Although not directly :(
    }
}

I expected to be able to access through the dot notation "eleventh" field of class Powers through an object of class SuperPowers within the class Powers. I also tried to let TestPowers extends Powers, but it doesn't work either. Why?


Solution

  • TestPowers cannot access eleventh. Yes, when you write sp.eleventh, you are trying to directly access the property via TestPowers from SuperPowers.

    Because of the protected access for eleventh, in Powers, and SuperPower being the child class of Powers, you are able to do this.eleventh or more accurately super.eleventh in SuperPowers. But the protected chain ends there. SuperPower, by inheritence, also "declares" eleventh as protected.

    So when you write

    SuperPowers sp = new SuperPowers();
    System.out.println(sp.eleventh);
    

    in TestPowers class you are trying to access eleventh property of SuperPowers from TestPowers. But SuperPowers declares eleventh as protected. Therefore causing an error in your code.

    So in order to access eleventh via direct access(from the SuperPowers object) you either need to extend SuperPowers on the TestPowers class or a better way is to generate a public getter for the property eleventh in the SuperPowers class like so:

    public int getEleventh(){
      return this.elventh;
    }
    

    then you can call the getter like so:

    SuperPowers sp = new SuperPowers();
    System.out.println(sp.getEleventh());