You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java向上转型中构造器赋值与子类字段重定义的访问差异问题

为什么向上转型后子类字段赋值的两种情况结果不同?

这个问题的核心在于:Java的实例字段不支持多态,只有方法具备多态特性,当子类定义与父类同名的字段时,会触发**字段隐藏(Field Hiding)**机制,这和方法重写完全是两回事。

第一种情况:子类直接修改父类继承的字段

当子类没有重新定义name和age字段时,子类对象中只存在一套从父类继承来的name和age字段。子类构造器中的this.name = "Child name",本质是修改了继承自父类的字段值。

向上转型为Parent类型后,引用p指向的是子类对象,此时访问的字段已经被子类修改过,所以输出Child name。

第二种情况:子类重新定义同名字段(字段隐藏)

当子类重新定义public String name;和public int age;时,子类对象中会同时存在两套字段:

  • 父类的name(初始值Parent name)和age(初始值30)
  • 子类自己的name(赋值为Child name)和age(赋值为10)

子类构造器中的this.name = "Child name",只是给子类自己的字段赋值,父类的字段完全没被修改。

向上转型为Parent类型后,编译器会严格按照引用的静态类型(Parent)来访问字段,所以会直接取父类的name字段值,输出Parent name。

验证补充

如果在第二种情况中,用子类引用访问字段,会得到子类自己的字段值:

Child c = new Child();
System.out.println(c.name); // 输出 Child name

如果想在子类中访问父类被隐藏的字段,可以用super关键字:

public class Child extends Parent {
    public String name;
    public int age;

    public Child() {
        this.name = "Child name";
        this.age = 10;
        System.out.println(super.name); // 输出 Parent name
    }
}

总结建议

字段隐藏是Java允许但不推荐的不良实践,会导致代码逻辑混淆。如果需要修改父类字段的取值,推荐:

  • 直接在子类中修改继承的字段(第一种方式)
  • 给父类添加setter方法,通过方法调用修改字段值(更符合面向对象封装原则)

内容的提问来源于stack exchange,提问作者Юрий Зайцев

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:40:36