如何初始化超级class构造函数所需的childclass中的参数Objects?

How to initialize parameter Objects in child class needed for super class constructor?

所以,这听起来可能有点奇怪,但让我解释一下。我有一个需要多个参数的超级class。一个这样的参数是 BufferedImage object。现在显然,要在 child class 中初始化此 BufferedImage 以用作参数,我需要使用 try 和 catch 块。我能做到的唯一方法是在构造函数中调用 child class 的方法。问题是,super() 构造函数必须是 child class 构造函数中的第一件事。所以我不能在调用super()之前调用初始化我的BufferedImage的方法。在 child class 构造函数中调用 super() 时,如何在将 BufferedImage object 用作参数之前正确初始化它?

示例:Super/Parent Class

public class CombatEntity {
    BufferedImage sprite; 
    public CombatEntity(String name, BufferedImage sprite) {
        //do something
    }
}

示例:Child Class

public class Batman {
     BufferedImage sprite;
     Batman() {
         super("Bruce Wayne", sprite); //sprite hasn't been properly initalized

     }

     void getSprite() { //I need to call this method before super in order to initalize my image
          try {
              File f = new File("Batman.png");
              sprite = ImageIO.read(f);
          }

          catch(Exception e) {
              //whatever
          }

     }

}

解决此问题的唯一方法是在 Batman 构造函数中要求一个 Image 参数。这个问题并不少见,也是遵守 Javabeans 模式的原因之一,其中每个 class 都有一个空构造函数以及 getter 和 setter。

做这样的事情:

在父级 class 创建普通构造函数,它接受名称和精灵参数。按照 JavaBeans 规范生成 getters 和 setters 方法。

CombatEntity:

   public class CombatEntity {

    protected String name;

    protected BufferedImage sprite; 

    public CombatEntity(String name, BufferedImage sprite) {
        this.name = name;
        this.sprite = sprite;
    }

    /*
     * Getters and Setters 
     */

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BufferedImage getSprite() {
        return sprite;
    }

    public void setSprite(BufferedImage sprite) {
        this.sprite = sprite;
    }   
}

在蝙蝠侠(子)中 class 创建两个构造函数 - 一个没有参数,您可以在初始化精灵图像之前使用它来创建蝙蝠侠对象,第二个类似于父构造函数。当您调用不带参数的构造函数时,它会调用父构造函数并将其参数设置为默认值。然后你可以执行 generateSpriteImage(String spriteImagePath) 从注入路径创建精灵图像。

Batman:

public class Batman extends CombatEntity{

    //Default constructor with no parameters 
    public Batman(){
        super("", null);
    }

    public Batman(String name, BufferedImage sprite){
        super(name, sprite);
    }

    public void generateSpriteImage(String spriteImagePath) {
        try {
            File file = new File(spriteImagePath);
            this.sprite = ImageIO.read(file);
        }

        catch(Exception e) {
            //whatever
        }
   }
}

希望对您有所帮助。

您的 CombatEntity 可以定义 abstract 方法 getSprite() 并在构造函数中调用该方法。 child class (蝙蝠侠) 将不得不实现此方法。

优点是在构造 object 后不需要调用额外的方法(如其他答案中所建议)。