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

父类非抽象方法无法访问子类同名属性的问题求助

问题分析与解决:Java继承中父类方法无法访问子类属性的问题

你碰到的这个问题其实是Java继承里典型的变量隐藏问题,核心原因很简单:父类的私有属性和子类的同名属性完全是两个毫不相干的变量,父类的checkFade方法根本看不到子类里的那两个属性,自然只会操作自己的私有变量。

为什么会这样?

  • 父类中用private修饰的fadeTriggered和flagFade是严格封装在父类内部的,子类无法继承,也不能直接访问。
  • 你在BackgroundSnow里重新定义了protected boolean fadeTriggered和protected int flagFade,这相当于在子类里新建了两个完全独立的成员变量,和父类的同名变量没有任何关联。当你调用父类的checkFade方法时,方法里操作的始终是父类自己的那两个私有属性,和子类的属性完全不搭边。

解决办法(两种推荐方案)

方案一:调整父类属性权限,子类不再重复定义同名属性

这是最符合继承设计思路的方案:把父类的私有属性改成protected(或者保持private但提供getter/setter),让子类可以继承这些属性,不需要自己重新定义。

修改后的父类代码:

public abstract class Background { 
    // 将私有属性改为protected,允许子类继承访问
    protected boolean fadeTriggered; 
    protected int flagFade; 

    // 保留必要的getter/setter方法,方便外部或子类操作
    public boolean getFadeTriggered() {
        return fadeTriggered;
    }

    public void setFadeTriggered(boolean fadeTriggered) {
        this.fadeTriggered = fadeTriggered;
    }

    public int getFlagFade() {
        return flagFade;
    }

    public void setFlagFade(int flagFade) {
        this.flagFade = flagFade;
    }

    // 新增抽象方法getID,强制子类实现
    public abstract int getID();

    public void checkFade(Background fadeFrom, Background fadeInto, SpriteBatch batch, ParallaxBackground parallaxBackground) { 
        //Clean up 
        if (fadeFrom.getFadeTriggered()) { 
            fadeFrom.setFadeTriggered(false); 
            if (fadeFrom.getFlagFade() > 0) { 
                fadeFrom.setFlagFade(0); 
            } 
        } 
        //Fade 
        if (!fadeTriggered) { 
            fadeTriggered = true; 
            flagFade = 1000; 
        } 
        if (flagFade > 0) { 
            parallaxBackground.draw(batch, this.getID(), 1); 
            parallaxBackground.draw(batch, fadeInto.getID(), flagFade * .001f); 
            flagFade--; 
        } else { 
            parallaxBackground.draw(batch, this.getID(), 1f); 
        } 
    } 
}

修改后的子类代码(删除重复属性,实现抽象方法):

public class BackgroundSnow extends Background { 
    private ArrayList<ParallaxTexture> textures; 
    private int textureCount; 
    private final String biomeName = "Default"; 
    private final int id = 1; 

    // 删掉重复定义的fadeTriggered和flagFade,直接继承父类的属性

    public BackgroundSnow() { 
        int i = 1; 
        while (true) { 
            if (!Gdx.files.internal("backgrounds/parallax/" + biomeName + "/img" + i + ".png").exists()) { 
                this.textureCount = i - 1; 
                break; 
            } 
            i++; 
        } 
        Printer.debugPrintToConsole(ParallaxBackground.class, "Parallax Backgrounds found: " + Integer.toString(textureCount)); 
        textures = new ArrayList<>(); 
        for (int j = 1; j < textureCount + 1; j++) { 
            textures.add(new ParallaxTexture(j, biomeName)); 
        } 
    } 

    // 实现父类的抽象getID方法
    @Override
    public int getID() {
        return id;
    }
}

方案二:父类属性保持私有,方法内用getter/setter操作属性

如果不想修改父类属性的访问权限,那可以把checkFade方法里直接操作属性的地方全部换成getter/setter调用,这样方法里操作的就是当前实例(子类继承的父类属性):

比如父类的checkFade方法里的这段代码:

//Fade 
if (!fadeTriggered) { 
    fadeTriggered = true; 
    flagFade = 1000; 
}

改成:

//Fade 
if (!getFadeTriggered()) { 
    setFadeTriggered(true); 
    setFlagFade(1000); 
}

同理,其他直接访问flagFade的地方也换成getFlagFade()和setFlagFade(),这样就能保证操作的是当前实例的属性,而不是父类自己的私有变量。

额外注意事项

  • 绝对不要在子类中重新定义和父类同名的属性,这种变量隐藏的做法会让代码逻辑变得混乱,是非常糟糕的编码习惯。
  • 继承的核心是复用父类的特性,子类只需要专注于实现自己特有的属性和方法,或者重写父类的方法来改变行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:34:53