Java 为什么继承类的实例可以';t访问不同包中基类的受保护成员

Java 为什么继承类的实例可以';t访问不同包中基类的受保护成员,java,Java,我有三个等级A、B、C: package com.training.protectedclass.A; public class A { protected int value; } 当继承的类存在于基类以外的包中时,它无法访问基类的受保护成员。但是,当这三个类都存在于同一个包中时,上述错误就会消失,并且代码编译时不会出现错误 有人能给我解释一下上面代码中每个错误的原因吗 谢谢:)这是因为Java中受保护的意味着两件事:1)继承的类可以看到它们继承的受保护成员,2)相同包

我有三个等级A、B、C:

package com.training.protectedclass.A;

public class A
{
    protected int   value;
}

当继承的类存在于基类以外的包中时,它无法访问基类的受保护成员。但是,当这三个类都存在于同一个包中时,上述错误就会消失,并且代码编译时不会出现错误

有人能给我解释一下上面代码中每个错误的原因吗


谢谢:)

这是因为Java中受保护的
意味着两件事:1)继承的类可以看到它们继承的受保护成员,2)相同包中的其他类可以看到受保护成员(即使它们不继承该成员)

因此,在类
B
中,您继承了
value
,因此您可以通过
this.value
访问它,但由于类
A
在另一个包中,您无法看到
A.value
。这是因为当您调用
a.value
时,您正在访问另一个包中的类成员,而不是字段
value
的继承版本

在类
C
的情况下,您不能访问
B
的任何受保护成员,因为您既不是从
B
继承的,也不是与
B
在同一个包中,因此通过以下方式定义受保护的访问修饰符:

对象的受保护成员或构造函数可以从包的外部访问,在包中它只能由负责该对象实现的代码声明

当你有
this.value=10,B对象访问它自己的成员之一,该成员是在超类中声明的受保护字段。另一方面,当您拥有
新的A().value
时,B对象会尝试访问它未实现的对象的受保护成员。

中的文档会这样说

受保护的修改器指定只能访问该成员 在其自己的包内(与包专用一样),并且 它的类在另一个包中的子类

但您的问题是,您试图访问的对象与
不同的受保护成员。看看这个

我想它给出了答案:

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

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

如果通过限定名称Q.Id进行访问,其中Q是 ExpressionName,则仅当类型为 表达式Q的子类是S或S的子类

如果通过字段访问表达式E.Id进行访问,其中E是 主表达式,或通过方法调用表达式E.Id(…), 其中E是主表达式,则如果且 仅当E的类型是S或S的子类时


您正在访问
B
正文中的成员
值。因此,对于应用此子句,S是
B
,根据最后一段,当您尝试访问某些表达式E的
E.value
时,仅当E的类型是B或B的子类时,才允许访问。由于类型是a,而不是B的子类,因此此条件失败

这是因为C没有扩展B。可见性是不可传递的。非常感谢,现在我理解了上述情况。谢谢你的帮助:)谢谢你的帮助:)谢谢你的帮助;)
package com.training.protectedclass.B;
import com.training.protectedclass.A.A;

public class B extends A
{
    public void test()
    {
        this.value = 10;
        A a = new A();
        a.value = 12; //Error => The field A.value is not visible
    }
}
package com.training.protectedclass.C;

import com.training.protectedclass.B.B;
import com.training.protectedclass.A.A;

public class C extends A
{
    public void test()
    {           
        B b = new B();
        b.value = 45; //Error => The field A.value is not visible
    }
}