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

Java子类变量值访问问题:父类引用指向子类实例时如何获取正确值

问题分析与解决方案

首先得明确:你遇到的是Java里**字段隐藏(Field Hiding)**的问题——子类的corners并没有重写父类的同名字段,而是把它"藏"起来了。Java的字段不支持多态,当你用父类类型的引用d访问字段时,编译器只会根据引用的静态类型(也就是Shape)来查找字段,所以拿到的是父类的0。

不过完全可以在不改变d的类型的情况下拿到子类的3,有两种常用方案:

方案1:用Getter方法(最推荐,符合面向对象规范)

这是最标准的做法,利用Java方法的多态特性来实现。给父类添加一个获取字段的方法,子类重写它:

public class Testclass {
    public static void main(String[] args) {
        Shape d = new Triangle();
        System.out.println(d.getCorners()); // 输出3
    }
}
class Shape{
    int corners = 0;
    
    // 父类定义获取方法
    public int getCorners() {
        return corners;
    }
}
class Triangle extends Shape{
    int corners = 3;
    
    // 子类重写方法,返回自己的字段值
    @Override
    public int getCorners() {
        return corners;
    }
}

原理:方法是支持多态的,当父类引用调用getCorners()时,JVM会根据对象的实际类型(Triangle)来执行子类的重写方法,自然就能拿到3。而且这种方式还遵循了封装原则,避免直接暴露字段。

方案2:强制类型转换(应急方案,不推荐)

如果没办法修改父类和子类的代码,那可以把d强制转换成Triangle类型后再访问字段:

public class Testclass {
    public static void main(String[] args) {
        Shape d = new Triangle();
        // 先判断类型,避免ClassCastException
        if (d instanceof Triangle) {
            System.out.println(((Triangle) d).corners); // 输出3
        }
    }
}

注意:一定要先通过instanceof判断类型,不然如果d实际指向的不是Triangle实例,会抛出ClassCastException异常。这种方式虽然能解决问题,但破坏了封装,也不够灵活,只适合临时应急。

总结:优先用第一种Getter方法的方案,既安全又符合面向对象的设计思想;第二种方案只在无法修改类结构时使用。

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:30:17