11

这是同一问题的稍微详细的版本。

我们无法访问子类中的(超类的)受保护变量,子类在不同的包中。我们只能访问超类的继承变量。但是,如果我们将修饰符更改为“受保护的静态”,那么我们也可以访问超类的变量。为什么会这样。?

这是我试图解释的代码片段。

package firstOne;

public class First {
    **protected** int a=7;
}

package secondOne;

import firstOne.*;

public class Second extends First {
    protected int a=10; // Here i am overriding the protected instance variable

    public static void main (String [] args){
        Second SecondObj = new Second();
        SecondObj.testit();
    }
    public void testit(){
        System.out.println("value of A in Second class is " + a);
        First b = new First();
        System.out.println("value in the First class" + b.a ); // Here compiler throws an error.
    }
}

上述行为是预期的。但我的问题是,如果我们将超类实例变量“a”的访问修饰符更改为“受保护的静态”,那么我们也可以访问该变量(超类的变量)......!我的意思是,

package firstOne;

public class First {
    **protected static** int a=7;
}

package secondOne;

import firstOne.*;

public class Second extends First {
    protected int a=10;

    public static void main (String [] args){
        System.out.println("value in the super class" + First.a ); //Here the protected variable of the super class can be accessed..! My question is how and why..?
        Second secondObj = new Second();
        secondObj.testit();
    }

    public void testit(){
        System.out.println("value of a in Second class is " + a);
    }

}

上面的代码显示了输出:

超类 7 中的价值

test1 类中 x 的值为 10

这怎么可能...?

4

2 回答 2

4

从“检查对 Java 虚拟机中受保护成员的访问”:

假设m是在属于包p的类c中声明的成员。如果m是公共的,它可以被任何类(代码中)访问。如果m是私有的,则只能由c访问。如果m具有默认访问权限,则只能由属于p的任何类访问。

如果m受到保护,事情会稍微复杂一些。首先,任何属于p的类都可以访问m,就好像它具有默认访问权限一样。此外,它可以被属于与p不同的包的c的任何子类s访问,但有以下限制:如果m不是静态的,则正在访问其成员的对象的类o必须是s或 a s 的子类,写成os(如果m是静态的,则限制不适用:m始终可以通过)

我在JLS 的第 6.6.2.1 节中找到了该引用,它支持关于“正在访问其成员的对象必须是s或子类......”的部分。我没有看到任何支持静态子句的东西,但是根据您自己的示例,这显然是正确的。

于 2013-06-24T04:00:37.803 回答
0

覆盖仅适用于方法,不适用于类变量。没有覆盖变量的事情。您正在隐藏超类的符号访问变量 a 。

于 2015-10-20T09:07:39.287 回答