【发布时间】:2019-08-07 17:05:10
【问题描述】:
这是一个受保护的继承问题。我确实理解 protected 意味着在一个包中,它就好像它是公共的。在包之外,一般来说,只有在子类内部时才能访问它。那不是我的困惑。我的困惑在于正在发生的一个小问题,我不知道为什么。我将在代码之后解释问题的核心。您将获得包含 TestA 类的包 com.wobble.foo 和包含扩展类 A 的 TestB 类的 com.wobble.bar。
//A Package
package com.wobble.foo;
public class TestA{
static protected int x = 5;
protected int y = 6;
}
//A different Package
package com.wobble.bar;
public class TestB extends TestA{
static{
TestA t = new TestA();
t.x = 1; //compiles
t.y = 2; //field not visible, fails to compile
}
}
超类有两个受保护的变量,一个是静态的。不同包中的子类创建了一个新的超类对象,试图访问这两个变量。为什么你可以通过对象通过它访问静态变量,但不能通过它访问实例变量?它们都受到保护。两人同班。两者都由同一个对象访问。请注意,对于那些认为这可能是重复的人:其他问题只是询问受保护的工作原理,但他们没有提出具体问题,即为什么只能访问这两个受保护的变量中的一个。
这不是一个如何修复代码的问题。我知道如何让最终游戏发挥作用。问题是为什么它可以通过t.x; 而不是t.y; 访问?
【问题讨论】:
-
您永远不会在代码中实例化 TestB 对象,代码的最后三行位于静态初始化块中,不需要实例即可运行。
-
另外:
t.x应该是T.x(因为它是一个静态方法调用);如果您的代码只是在TestB对象的非静态方法中运行,您将能够访问y;您甚至不需要说出对象名称y而不是t.y。 -
@MikaelF 无论我将代码放在静态初始化程序还是实例初始化程序中,都不会改变结果。重点是通过 TestA 对象访问它。
-
T.y不可访问,因为作为受保护的字段,它只能被其后代访问(在本例中为t)。但是,您不是从t访问它,而是从类TestA内的一个静态块访问它。受保护类似于私有,但类可以访问它们从父类继承的字段和方法。 -
@user11214549 您可以通过两种方式看到这一点:1) 您正在尝试访问
t的受保护成员,但它不会让您访问,因为您不是t(请参阅我关于受保护类似于私有的评论); 2)您正在从静态上下文访问非静态字段,这是您无法做到的。您的最后 3 行没有在t内运行;相反,它们是静态运行的,不属于任何特定实例。不在t内部运行的代码看不到t不会在其自身及其依赖项之外显示的字段。此外,t.x具有误导性,因为它实际上只是x(x是静态的)。
标签: java inheritance protected