如果覆盖一个类的子类中的字段,该子类有两个同名(且类型不同)的字段?

发布于 2025-01-08 10:26:52 字数 559 浏览 1 评论 0原文

我有 3 个类:

public class Alpha {
    public Number number;
}

public class Beta extends Alpha {
    public String number;
}

public class Gama extends Beta {
    public int number;
}

为什么下面的代码可以编译?而且,为什么测试能够通过而没有任何运行时错误?

@Test
public void test() {
    final Beta a = new Gama();
    a.number = "its a string";
    ((Alpha) a).number = 13;
    ((Gama) a).number = 42;

    assertEquals("its a string", a.number);
    assertEquals(13, ((Alpha) a).number);
    assertEquals(42, ((Gama) a).number);
}

I have 3 classes:

public class Alpha {
    public Number number;
}

public class Beta extends Alpha {
    public String number;
}

public class Gama extends Beta {
    public int number;
}

Why does the following code compile? And, why does the test pass without any runtime errors?

@Test
public void test() {
    final Beta a = new Gama();
    a.number = "its a string";
    ((Alpha) a).number = 13;
    ((Gama) a).number = 42;

    assertEquals("its a string", a.number);
    assertEquals(13, ((Alpha) a).number);
    assertEquals(42, ((Gama) a).number);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

空‖城人不在 2025-01-15 10:26:52

成员变量不能像方法一样被重写。 BetaGama 类中的 number 变量隐藏(而不是覆盖)成员变量 number超类的

通过强制转换,您可以访问超类中的隐藏成员。

Member variables cannot be overridden like methods. The number variables in your classes Beta and Gama are hiding (not overriding) the member variable number of the superclass.

By casting you can access the hidden member in the superclass.

清风挽心 2025-01-15 10:26:52

字段不能被覆盖;它们一开始就不是多态访问的——您只是在每种情况下声明一个新字段。

它可以编译,因为在每种情况下,表达式的编译时类型足以确定您指的是哪个名为number的字段。

在现实世界的编程中,您可以通过两种方法来避免这种情况:

  • 常识:隐藏字段会使您的代码更难阅读,所以不要这样做
  • 可见性:如果您将所有字段设为私有,子类将不会知道无论如何他们

Fields can't be overridden; they're not accessed polymorphically in the first place - you're just declaring a new field in each case.

It compiles because in each case the compile-time type of the expression is enough to determine which field called number you mean.

In real-world programming, you would avoid this by two means:

  • Common-sense: shadowing fields makes your code harder to read, so just don't do it
  • Visibility: if you make all your fields private, subclasses won't know about them anyway
海风掠过北极光 2025-01-15 10:26:52

Java 隐藏字段

当后继类的字段与超类的字段名称相同时,称为 - 隐藏字段 strong>

Java的字段不支持多态性,也不考虑字段的类型

class A {
    String field = "A: field";

    String foo() {
        return "A: foo()";
    }
}

class B extends A {
    //B's field hides A's field
    String field = "B: field";

    String foo() {
        return "B: foo()";
    }
}

@Test
public void testPoly() {
    A a = new A();
    assertEquals("A: field", a.field);
    assertEquals("A: foo()", a.foo());

    B b = new B();
    assertEquals("B: field", b.field);
    assertEquals("B: foo()", b.foo());

    //B cast to A
    assertEquals("A: field", ((A)b).field);  //<--
    assertEquals("B: foo()", ((A)b).foo());
}

[Swift重写属性]

Java Hiding a field

When successor has a field with the same name as a superclass's field it is called - Hiding a field

Java's field does not support polymorphism and does not take a field's type into account

class A {
    String field = "A: field";

    String foo() {
        return "A: foo()";
    }
}

class B extends A {
    //B's field hides A's field
    String field = "B: field";

    String foo() {
        return "B: foo()";
    }
}

@Test
public void testPoly() {
    A a = new A();
    assertEquals("A: field", a.field);
    assertEquals("A: foo()", a.foo());

    B b = new B();
    assertEquals("B: field", b.field);
    assertEquals("B: foo()", b.foo());

    //B cast to A
    assertEquals("A: field", ((A)b).field);  //<--
    assertEquals("B: foo()", ((A)b).foo());
}

[Swift override property]

稀香 2025-01-15 10:26:52

作为解决方法,您可以使用 getter 方法:

class A {
    private String field = "A: field";

    String getField() {
        return field;
    }
}

class B extends A {
    private String field = "B: field";

    @Override        
    String getField() {
        return field;
    }
}

As a workaround, you can use getter methods:

class A {
    private String field = "A: field";

    String getField() {
        return field;
    }
}

class B extends A {
    private String field = "B: field";

    @Override        
    String getField() {
        return field;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文