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

weylhg0b  于 2021-06-30  发布在  Java
关注(0)|答案(3)|浏览(438)

我有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);
}
yfwxisqw

yfwxisqw1#

字段不能被覆盖;它们一开始不是以多态方式访问的——您只是在每种情况下声明一个新字段。
它编译是因为在每种情况下,表达式的编译时类型都足以决定调用哪个字段 number 你是说。
在实际编程中,您可以通过两种方法避免这种情况:
常识:隐藏字段会使代码更难阅读,所以不要这样做
可见性:如果将所有字段都设为私有字段,子类无论如何也不会知道它们

nwo49xxi

nwo49xxi2#

当后继者有一个与超类字段同名的字段时,称为隐藏字段
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覆盖属性]

bvpmtnay

bvpmtnay3#

成员变量不能像方法一样被重写。这个 number 类中的变量 Beta 以及 Gama 正在隐藏(而不是重写)成员变量 number 超类的。
通过强制转换,可以访问超类中的隐藏成员。

相关问题