Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如果覆盖一个类的子类中的字段,该子类是否有两个名称相同(类型不同)的字段?_Java_Subclassing_Jls - Fatal编程技术网

Java 如果覆盖一个类的子类中的字段,该子类是否有两个名称相同(类型不同)的字段?

Java 如果覆盖一个类的子类中的字段,该子类是否有两个名称相同(类型不同)的字段?,java,subclassing,jls,Java,Subclassing,Jls,我有三门课: 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

我有三门课:

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);
}
字段不能被覆盖;首先,它们不是以多态方式访问的——您只是在每种情况下声明一个新字段

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

在现实编程中,您可以通过两种方式避免这种情况:

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

成员变量不能像方法一样被重写。类
Beta
Gama
中的
number
变量隐藏了超类的成员变量
number


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

当后继者具有与超类字段同名的字段时,它被称为-隐藏字段

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());
}
A类{
String field=“A:field”;
字符串foo(){
返回“A:foo()”;
}
}
B类扩展了A类{
//B的字段隐藏A的字段
String field=“B:field”;
字符串foo(){
返回“B:foo()”;
}
}
@试验
公共void testPoly(){
A=新的A();
资产质量(“A:字段”,A.字段);
assertEquals(“A:foo()”,A.foo());
B=新的B();
资产质量(“B:字段”,B.字段);
assertEquals(“B:foo()”,B.foo());
//B投给A

assertEquals(“A:field”,((A)b.field);//和?它是这样工作的。如果需要重写,应该使用setter/getter方法。公共字段几乎总是个坏主意。请参阅Java中的™ 教程