一个受保护的变量是可访问的,而另一个则不是。为什么?

这是一个受保护的继承问题。我确实理解受保护意味着在包中,它就像是公共的一样。在包外部,一般来说,它只有在子类内部时才可以访问。这不是我的困惑。我的困惑在于正在发生的一个小挑剔,我不知道为什么。我将在代码之后解释问题的胆量。您将获得包含 TestA 类的包 com.wobble.foo 和 com.wobble.bar 它包含扩展类 A 的 TestB 类。


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


慕斯王
浏览 94回答 1
1回答

aluckdog

 t.x = 1; //compiles这是一个字段。所以你应该把它写成(会有一个编译器警告)。staticTestA.x静态受保护字段可从子类的静态代码(或从非静态代码中)访问。 t.y = 2; //field not visible, fails to compile这是一个实例字段。可以从子类上的实例方法中访问受保护的实例字段。但只能从这些方法中。不能从静态方法调用它们(即使该静态方法恰好位于子类上)。如果需要从另一个类中的静态方法访问字段,则需要公开该字段或将需要它的代码移动到同一包中。但只能从这些方法中。而且,只有当您可以确定所讨论的实例实际上来自您自己的类时。在您的示例中TestA t = new TestA();t.y = 2;t.y不可见,因为 中的代码无法访问 中的实例上的受保护字段。它需要是 TestB 的一个实例。不过,相同的代码可以在 上的方法中工作。TestBTestATestA以下方法也不起作用:// in TestBvoid boo(TestA someInstance){   this.y = someInstance.y;    // does not compile, because someInstance.y is not visible   // because it could be from unknown TestC}好吧,这是有道理的,但是我该如何访问t.x?它也是一个受保护的成员,我仍然不是t。此处根本不使用该实例(它甚至可能为 null,代码仍然有效)。静态方法仅在变量的编译时(声明)类型上调度。理想情况下,甚至不应该被允许,但至少你会得到一个编译器警告。tt.x它是静态的,所以从技术上讲,你不是通过超类访问它,而是通过子类访问它?即 t.x -> x -> TestB.x 通过 TestB 获取它?子类不能重写静态方法。 只是一种令人困惑(或方便,取决于你如何看待它)的写作方式。您可以将其视为从父类自动导入所有(公共和受保护的)静态字段和变量的子类。使击键次数减少,但不会改变行为(当然,其工作原理与实例方法非常不同,实例方法在实际实例类型上动态调度)。TestB.xTestA.x无论哪种方式,由于受保护,因此 可由 的子类中的静态代码块访问,包括 。TestA.xTestATestB
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java