【问题标题】:Getters and setters in abstract class?抽象类中的getter和setter?
【发布时间】:2026-02-21 06:35:01
【问题描述】:

我正在使用 Java 开发游戏,但在使用抽象类中的 setter 和 getter 时遇到问题。假设这个类看起来像这样:

public abstract class Objects {
    protected int velX, velY;

    public Objects(int velX, int velY){
        this.velX = velX;
        this.velY = velY;
    }

    //getters, setters and other methods
}

现在,如果我想在一个不扩展抽象类 Objects 的类中使用这些方法,它就不能正常工作。游戏将运行,但当它尝试使用 getter 和 setter 执行部分代码时会抛出 NullPointerException。例如:

public class HUD {
    private Objects o;

    public HUD(......)

    public void someMethod(){
        if (o.getVelX > 0){
            o.setVelY(3);
        }
    }
}

这只是一个不好的例子,但如果我运行它会抛出 NullPointerException。我必须以不同的方式初始化类 Objects 吗?

【问题讨论】:

  • 是的,你需要实例化 Objects 来执行 getter/setter,前提是 getter/setter 是公开的。
  • Objects o 是否在构造函数 HUD(........) 中初始化?否则它将为 null,您将得到 nullpointerexception
  • 是的,它们是公开的。我无法实例化对象,因为它是抽象的。我不在 HUD 构造函数中调用 super()
  • 要使用抽象类,您需要对其进行子类化。然后getVelX(),如果公共或受保护方法的行为就像它在你的类中一样。如果 Objects 和 HUD 之间的关系不是 is-a relationship,请过度考虑您的类设计。
  • 抽象类的重点是你需要实例化一个子类来使用它。如果您不实例化子类,请使其不抽象并实例化类本身。

标签: java abstract-class setter getter getter-setter


【解决方案1】:

我要使用o,您必须使用对扩展您的 Objects 抽象类的具体类的实例的引用来初始化它。否则o 保持为空,任何对o.something 的调用都会抛出NullPointerException。这与 setter 或 getter 无关。

【讨论】:

    【解决方案2】:

    您需要为示例 ObjectsChild 创建新的非抽象类,然后首先在构造函数 HUD() 中初始化您的 o 对象:

    private Objects o;
    
    public HUD() {
        this.o = new ObjectsChild();
    }
    

    之后,您可以在此 o 对象上调用 getter 和 setter。

    【讨论】:

    • Objects 不是抽象的,他不能创建实例吗?
    • 是的,我不能这样做。
    • @wonderb0lt 看我的更新,可以初始化一个抽象类的实例,只需要在原地实现所有抽象方法即可。
    【解决方案3】:

    定义非原始字段时,默认值为null,所以你的o字段为null。你需要在你的构造函数中初始化它,或者至少在你调用它的任何方法之前。

    public class HUD {
        private Objects o;
    
        public HUD(......){
           o = new Objects();//or a class that extends your abstract Objects class
        }
    
    public void someMethod(){
        // at this poing you need to have o initialized
        if (o.getVelX > 0){
            o.setVelY(3);
        }
    }
    }
    

    更新

    您可以初始化Objects 实例,但这将是一个匿名类,您需要在此处实现所有抽象方法:

    o = new Objects(){
       @Override
       public void myAbstractMethod(){
         ...
       }
    }
    

    至于 NPE,你可以使用 guava 或 JDK8 中的Optional 来避免它。

    【讨论】: