了解类中受保护成员的行为

时间:2013-07-07 21:29:46

标签: java inheritance packages protected

我试图了解类中受保护成员的行为。我有一个类TopClass,其中包含受保护的整数pr

类别:

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;
    }
}

还有另一个包com.test.anotherpackage,其中有3个类SubClass1SubClass2SubClass3。继承层次结构如下:

  1. SubClass1 extends TopClass
  2. SubClass2 extends SubClass1
  3. SubClass3 extends SubClass2
  4. 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)
        }
    }
    

    在上面的代码中,(1)(2)(3)(5)(6)(9)完美运行,没有任何可见性问题。但(4)(7)(8)存在可见性问题。

    根据JLS§6.6.2.1

      

    设C是声明受保护成员的类。访问是   只允许在C的子类S的主体内使用。

         

    此外,如果Id表示实例字段或实例方法,则:

         

    如果访问是通过限定名称Q.Id,其中Q是   ExpressionName,当且仅当类型时才允许访问   表达式Q是S或S的子类。

         

    如果访问是通过字段访问表达式E.Id,其中E是a   主表达式,或方法调用表达式E.Id(...),   其中E是主表达式,如果和,则允许访问   只有当E的类型是S或S的子类时。

    我试图理解这就是if the type of the expression Q is S or a subclass of S出现的原因。是否有任何具体方案可以使这种实施有益?任何相关的例子将受到高度赞赏。我试着在SO上查找它,但找不到可以解决我怀疑的解释。

1 个答案:

答案 0 :(得分:0)

您正在讨论的表达式也是代码中负责您的问题的表达式:

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

(2)因为表达式s2的类型是SubClass1的子类 (4)因为表达式s1的类型不是SubClass2的子类 (5)因为表达式s3的类型是SubClass2

的子类

然而,我不知道

  

此实施可能有益的任何特定情况

或者