2

我想用 java 编写一个程序,它由三个类组成,A,BC, 这样可以B扩展AC扩展B。每个类都定义了一个实例变量(名为“x”)。

如何在不更改或版本的情况下编写方法C来访问A'sx 的版本并将其设置为给定值?BC's

我试过 super.x了,但这不是真的。

有什么帮助吗?提前感谢您的关注

4

3 回答 3

3

您可以像这样访问 A 的版本x

((A)this).x

只要x没有private在类中声明A。我刚刚测试过了。

请注意,对于字段,没有覆盖(就像方法一样)。因此,对于 C 类的对象,将存在三个x字段,但其中两个不能正常访问,因为它们被另一个名为 的字段隐藏x。但是,如果没有隐藏它本来是可见的,那么像上面那样投射对象将使您能够得到它。

我认为在一个类及其子类中声明同名字段是非常糟糕的做法。这很令人困惑。A如果你有一个类,然后你改变了实现A并添加了一个新的私有字段,它就可以合法地发生z;在这种情况下,可能无法确保没有A已经有 field的子类z,因为您甚至不总是知道所有子类是什么(A例如,如果是您公开分发的类)。我认为正是出于这个原因,Java 允许您拥有相同名称的字段,以及为什么隐藏规则是它们的方式,因为它允许这样的事情在不破坏所有其他子类的情况下工作。不过,除此之外,我建议不要在超类和子类中具有相同名称的字段。不过,如果他们都是private这样,也许会没事的。

于 2013-09-27T18:33:36.417 回答
2

我误读了你的问题。你不能做你想做的事。

扩展类意味着在多个层中添加信息,最终产生一个对象。虽然有多个层,但这并不意味着这些层是相互分离的。

变量 X 将在一个级别(可能A)定义,之后其他类将使用此变量(如果已声明protected),但它们不会拥有自己的副本。您只能访问您的直接超类。
这个类可能会给你额外的访问它自己的超类,但你没有直接接触到超超类。

于 2013-09-27T18:17:44.643 回答
2

请执行下列操作

public static void main(String[] args) throws Exception {
    C c = new C();
    System.out.println("c:" + c.x);
    System.out.println("a:" + ((A)c).x);
    c.changeAX();
    System.out.println("c:" + c.x);
    System.out.println("a:" + ((A)c).x);
}

static class A {
    int x;
}

static class B extends A {
    int x;
}

static class C extends B {
    int x;

    public void changeAX() {
        ((A)this).x = 4;
    }
}

字段是相对于引用的声明类型解析的。以上印刷品

c:0
a:0
c:0
a:4

该字段必须至少具有protected可见性。


你不想隐藏班级成员,这是不好的做法,因为它很容易让任何试图弄清楚你指的是哪个成员的人感到困惑。

于 2013-09-27T18:29:54.447 回答