实现子类中对象的实例化

时间:2014-08-29 17:20:32

标签: java inheritance

我在这里提出了一个非常简单的问题,但不知道搜索的方向......

我构建了一个使用未实例化对象扩展另一个类的类。我如何确保不忘记在子类中实例化对象?这就是我的意思:

public class Hitbox{
  .... 
}

public class Enemy{
  protected Hitbox hbox;  // edit: changed to protected
}

public class AngryLady extends Enemy{
  hbox = new Hitbox(10, 20);  // Must not forget this!
}

一种方法是在使用此句柄之前始终检查if (hbox!=null),但这感觉很愚蠢。必须有一种比抽象类更简单的方法,当抽象类中的方法尚未实现时,编译器已经给出了错误。

3 个答案:

答案 0 :(得分:2)

只需在父类的构造函数中初始化变量:

public abstract class Enemy{
    protected Hitbox hbox;
    public Enemy(int a, int b) {
        hbox = new Hitbox(a, b);
    }
}

public class AngryLady extends Enemy {
    public AngryLady(int a, int b) {
        super(a, b);
    }
}

如果HitBox的每个子类需要不同的Enemy实例,请使用Factory方法模式。这是一个非常简单的例子:

public enum HitboxType {
    ANGRY
}

public final class HitboxFactory {
    private HitboxFactory() {
    }

    public static Hitbox createHitbox(HitboxType hitboxType) {
        switch(hitboxType) {
            case HitboxType.ANGRY:
                return new AngryHitbox();
            case <another_case>:
                return <respective hitbox>
        }
        //in case of invalid parameter
        return null;
    }
}

使用依赖注入会更好:

public abstract class Enemy{
    protected Hitbox hbox;
    public Enemy(Hitbox hitbox) {
        hbox = hitbox;
    }
}

public class AngryLady extends Enemy {
    public AngryLady(Hitbox hitbox)) {
        super(hitbox);
    }
}

//...
AngryLady angryLady = new AngryLady(HitboxFactory.createHitbox(HitboxType.ANGRY));
//...

如果您不想null Hitbox,则另一个提示是创建一个空的Hitbox

public class EmptyHitbox extends Hitbox {
    public EmptyHitbox() {
        super(0,0); //or whatever arguments it needs
    }
}

在工厂方法中:

public static Hitbox createHitbox(HitboxType hitboxType) {
    switch(hitboxType) {
       /* ... */
    }
    //in case of invalid parameter
    return new EmptyHitbox();
}

答案 1 :(得分:2)

首先它应该是protected,因为子类无法访问private个字段。

public class Enemy{
  protected Hitbox hbox;
}

为了确保你不会忘记,你应该真正启动你声明它的对象 - 父类。

public class Enemy{
    //if you just don't want/need to define a constructor explicitly and you know a b ahead.
    int a = 0;
    int b = 0;
    protected Hitbox hbox = new Hitbox(a, b); 
}

在这种情况下,您始终可以在子类中使用hbox而无需担心。

答案 2 :(得分:1)

由于hbox字段是从父类继承的,因此应该在父类中初始化它:

public class Enemy {
    private final static int DEFAULT_H = 10;
    private final static int DEFAULT_W = 10; 
    // default initialization 
    private HitBox hbox = new HitBox(DEFAULT_W,DEFAULT_H); 

    public HitBox getHBox() { 
       return hbox; 
    }
}

除非必须为每个子类初始化hbox,否则您应该使用链式构造函数初始化HitBox

public class Enemy {

    private final HitBox hbox; 

    public Enemy(HitBox hbox) {
        this.hbox= hbox; 
    }


    public HitBox getHBox() { 
       return this.hbox; 
    }
}


public class AngryLady extends Enemy{
   public AngryLady() {
        super(new HitBox(10, 20));
   }
}

此示例假设Enemy不是抽象类。