【问题标题】:How to initialize parameter Objects in child class needed for super class constructor?如何初始化超类构造函数所需的子类中的参数对象?
【发布时间】:2015-12-22 21:10:31
【问题描述】:

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

示例:超级/父类

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

示例:子类

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
          }

     }

}

【问题讨论】:

    标签: java inheritance constructor superclass


    【解决方案1】:

    做这样的事情:

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

    战斗实体:

       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;
        }   
    }
    

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

    蝙蝠侠:

    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
            }
       }
    }
    

    希望这会对您有所帮助。

    【讨论】:

    • 好吧,看完这个答案,我觉得自己像个白痴。因为我实际上从来没有使用过这样的构造函数,所以我忘记了一个类可以有多个构造函数。脑残……不过还是谢谢你!这对我很有帮助。还要感谢@ControlAltDel,因为你也这么说。
    • 这就是多态性的力量。 :) 很高兴为您提供帮助!
    【解决方案2】:

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

    【讨论】:

    • Javabeans 模式?空构造函数?吸气剂和二传手?我从来没有听说过这些事情。你能详细说明一下吗?谢谢。
    【解决方案3】:

    您的CombatEntity 可以定义一个abstract 方法getSprite() 并在构造函数中调用它。子类(蝙蝠侠)必须实现此方法。

    优点是您在构造对象后不需要调用额外的方法(如另一个答案中所建议的那样)。

    【讨论】:

    • 好的,谢谢埃里克。我肯定也会考虑这种方法!
    猜你喜欢
    • 1970-01-01
    • 2017-01-12
    • 2013-10-25
    • 2016-01-05
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多