简体   繁体   中英

Accessing protected members outside package with child class reference

package pack1;
class A{
   protected void m1(){
      System.out.println("protected modifier");
   }
}

package pack2;
class B extends A{
    public static void main(string[]args){
         B b = new B();//Valid
         b.m1();

        A a = new B();//Invalid
          a.m2();

       A a1 = new A();//InValid
         a1.m1();

   }
}

Why while accessing protected members outside package we need to have child class reference only.?

Why we cant use parent reference to access protected members (Here A a = new B())?

I have gone through blogs and many stack overflow answers but didn't find any answer for WHY?.

so can anyone help me knowing the answer for WHY?

You are not allowed to access A because you are still outside of a subclass or package. The main method is static , thus unbound from instances of the B class. In order to access A you need to be inside the B class, so in a non-static context like

public class B extends A {
    public void foo() {
        m1(); // Valid call since inside subclass
    }
}

I think you have misunderstood what static means.


The details of protected are described in the Java Language Specification . Extract from JLS§6.6.2 :

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C .

The limitation even goes beyond your example. The key is " responsible for the implementation ". Compare that to the following example:

package a;

public class Point {
    protected int x;
    protected int y;
}
package b;

import a.Point;

public class Point3D extends Point {
    public void delta(Point other) {
        other.x += this.x;  // Compile-time error: Cannot access other.x
        other.y += this.y;  // Compile-time error: Cannot access other.y
    }
}

Though the class Point3D is a subclass of Point , it is not responsible for the implementation of the other object. Thus, it is not allowed to access its protected members.

Same for

public class B extends A {
    public void foo() {
        A other = new A();
        other.m1(); // Compile-time error
    }
}

since the current instance to which the foo() method call belongs to is not responsible for the implementation of other . Thus, access is not permitted.

The concept of inheritance/polymorphism makes the inherited public and protected methods and variables of the parent class - members of the child class and is therefore accessible to the objects of the child class. protected access requires two rules-

  1. can only be accessed by classes that are within the same package

  2. can be accessed via inheritance.

    A a = new B();

    a.m1(); //doesn't compile

This is an instance of the B class but as far as it is a reference of A, it is an A object. That is why the object "a" only has access to members that are common to A and B. ie object "a" as a reference of class A has access only to the inherited methods of class B. It does not have access to any method or class variable of B that is absent in A even though it is an instance of class B. You have to explicitly cast it to a B to give it access to unique methods & variables of class B. So, bearing this in mind, as far as Java is concerned, object "a" is a class A object that is in another package. Therefore even though the method a.m1 was inherited, "a" does not have access to it because it is an A object in another package. a.m1 will compile in pack1.

Contrast that with this code

B b = new B();
b.m1() //compiles

b is an object of B and therefore rule 2 of the protected access applies. Since m1 is an inherited protected method of the object B, it has full access to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM