我在这里提出了一个非常简单的问题,但不知道搜索的方向......
我构建了一个使用未实例化对象扩展另一个类的类。我如何确保不忘记在子类中实例化对象?这就是我的意思:
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)
,但这感觉很愚蠢。必须有一种比抽象类更简单的方法,当抽象类中的方法尚未实现时,编译器已经给出了错误。
答案 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
不是抽象类。