简体   繁体   中英

Understanding the behavior of protected members in class

I am trying to understand the behavior of protected member in a class. I have a class TopClass which contains protected integer pr .

Class:

package com.test;

import com.test.anotherpackage.SubClass1;
import com.test.anotherpackage.SubClass2;
import com.test.anotherpackage.SubClass3;

public class TopClass {
    protected int pr;

    void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
        t.pr = 3;
        s1.pr = 0;
        s2.pr = 1;
        s3.pr = 1;
    }
}

There is another package com.test.anotherpackage which has 3 classes SubClass1 , SubClass2 and SubClass3 . Inheritance hierarchy is as follows:

  1. SubClass1 extends TopClass
  2. SubClass2 extends SubClass1
  3. SubClass3 extends SubClass2

SubClass1

package com.test.anotherpackage;

import com.test.TopClass;

public class SubClass1 extends TopClass {

    void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
        t.pr = 0; // Error because not in same package.
        s1.pr = 0; //(1)
        s2.pr = 1; // Does not throw an Exception. Why? (2)
        s3.pr = 1; // (3)
    }
}

SubClass2

package com.test.anotherpackage;

import com.test.TopClass;

public class SubClass2 extends SubClass1 {
    void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
        t.pr = 0; // Error because not in same package.
        s1.pr = 0; // Throws Exception, why?  (4)
        s2.pr = 1; //  (5)
        s3.pr = 1; // Does not throw an Exception. Why?(6)
    }
}

SubClass3

package com.test.anotherpackage;

import com.test.TopClass;

public class SubClass3 extends SubClass2 {
    void action(TopClass t, SubClass1 s1, SubClass2 s2, SubClass3 s3) {
        t.pr = 0; 
        s1.pr = 0; // Not Visible (7)
        s2.pr = 1; // Not Visible (8)
        s3.pr = 1; // (9)
    }
}

In above code, (1) , (2) , (3) , (5) , (6) and (9) work perfectly without any visibility issues. But (4) , (7) , (8) have visibility issues.

According to JLS§6.6.2.1 ,

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.

In addition, if Id denotes an instance field or instance method, then:

If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.

If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.

Thing I am trying to understand here is why if the type of the expression Q is S or a subclass of S comes into picture. Is there any specific scenario in which this implementation can be beneficial? Any related example will be highly appreciated. I tried looking it on SO, but couldn't find an explanation which could solve my doubt.

The expression you're discussing is also the one responsible for your questions in the code:

if the type of the expression Q is S or a subclass of S

(2) because the type of the expression s2 is a subclass of SubClass1
(4) because the type of the expression s1 is not a subclass of SubClass2
(5) because the type of the expression s3 is a subclass of SubClass2

However, I don't know of

any specific scenario in which this implementation can be beneficial

either.

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