Java:无法访问扩展子类中超类的受保护成员

时间:2013-06-12 05:25:20

标签: java protected

我想就此进行一些讨论,但我无法推断出我案例的答案。仍然需要帮助。

这是我的代码:

package JustRandomPackage;

public class YetAnotherClass{
    protected int variable = 5;
}
    
package FirstChapter;

import JustRandomPackage.*;

public class ATypeNameProgram extends YetAnotherClass{
    public static void main(String[] args) {

        YetAnotherClass bill = new YetAnotherClass();
        System.out.println(bill.variable); // error: YetAnotherClass.variable is not visible

    }
}

以下一些定义,上面的例子似乎令人困惑:

 1. Subclass is a class that extends another class.
 2. Class members declared as protected can be accessed from 
    the classes in the same package as well as classes in other packages 
    that are subclasses of the declaring class.

问题:为什么我无法从子类int variable = 5实例(YetAnotherClass对象)访问受保护的成员(bill)?

5 个答案:

答案 0 :(得分:3)

作为声明类的子类的其他包中的类只能访问自己继承的protected成员。

public class ATypeNameProgram extends YetAnotherClass{
    public ATypeNameProgram() {
        System.out.println(this.variable); // this.variable is visible
    }
}

...但不是其他对象继承的protected成员。

public class ATypeNameProgram extends YetAnotherClass{
    public ATypeNameProgram() {
        System.out.println(this.variable); // this.variable is visible
    }

    public boolean equals(ATypeNameProgram other) {
        return this.variable == other.variable; // error: YetAnotherClass.variable is not visible
    }
}

答案 1 :(得分:2)

bill不是子类YetAnotherClass的一部分。 bill是一个单独的YetAnotherClass。

尝试int bill = this.variable;(在构造函数内)访问子类'members。

答案 2 :(得分:1)

如果YetAnotherClassATypeNameProgram位于同一个包中,您的代码将有效。正如其他人所写,在其他情况下不会起作用。这是工作示例。

package my.example;

public class MainClass extends MyAnotherClass {
    public static void main(String[] args) {
        MyAnotherClass bill = new MyAnotherClass();
        System.out.println(bill.value); // this will work
    }
}

package my.example;

public class MyAnotherClass {

    protected int value = 5;

}

答案 3 :(得分:1)

只有当Foo可分配给Bar时,类Bar才能访问Foo类型的受保护实例成员。即,如果我们可以写:

Foo foo = new Bar(); 

例如,假设我们有:

package a;

public class Base {
    protected int protectedField;
}

然后我们就可以了:

package b;

import a.Base;

public class Parent extends Base {
    void foo() {
        int i = this.protectedField;
    }
    void foo(Parent p) {
        int i = p.protectedField;
    }
    void foo(Child c) {
        int i = c.protectedField;
    }
}

class Child extends Parent { }

这将编译,因为所有protectedField都是通过Parent的实例访问的。请注意,由于Parent引用可以是Child个实例(即我们可以写Parent p = new Child();),因此我们可以访问c.protectedField

以下编译:

package b;

import a.Base;

public class Parent extends Base {
    void foo(Stepchild sc) {
        int i = sc.protectedField; // ERROR
    }
}

class Stepchild extends Base {}

因为Stepchild的实例不是Parent的实例。

有些令人困惑,这不会编译:

package b;

import a.Base;

public class Parent extends Base {}

class Child extends Parent {
    void foo(Parent p) {
        p.protectedField; // ERROR
    }
}

这是因为Parent对象不是Child的超类或超级接口,因此Child无法访问其受保护的成员。

如果您在记忆时遇到问题,只需考虑该类型是否可以写入类的类型的引用。例如,我们可以写:

Parent p = new Child();

但不能写

Child c = new Parent();     // ERROR
Parent p = new Stepchild(); // ERROR

因此Child无法访问Parent个受保护的成员,Parent无法访问Stepchild& #39;受保护的成员。

最后几点:

请记住,protected访问权限允许在包中进行查看。根据我的经验,人们会忘记这一点。

最后,protected static成员始终在继承层次结构中可见。

答案 4 :(得分:0)

您不是要创建扩展它的类的实例,而是创建父类的实例。检查以下代码:

public class ATypeNameProgram extends YetAnotherClass{
    public static void main(String[] args) {

        YetAnotherClass bill = new YetAnotherClass();
        System.out.println(bill.variable); // error: YetAnotherClass.variable is not visible

        ATypeNameProgram a = new ATypeNameProgram();
        System.out.println(a.variable); //this will work

    }
}