Java 在子类中强制实例化对象
我这里有一个很简单的问题,但不知道该往哪个方向搜索 我构建了一个类,它用一个未实例化的对象扩展了另一个类。如何确保不会忘记在子类中实例化对象?我的意思是:Java 在子类中强制实例化对象,java,inheritance,Java,Inheritance,我这里有一个很简单的问题,但不知道该往哪个方向搜索 我构建了一个类,它用一个未实例化的对象扩展了另一个类。如何确保不会忘记在子类中实例化对象?我的意思是: public class Hitbox{ .... } public class Enemy{ protected Hitbox hbox; // edit: changed to protected } public class AngryLady extends Enemy{ hbox = new Hitbox(10,
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)
,但这感觉很傻。必须有一种更简单的方法,比如抽象类,当抽象类中的方法尚未实现时,编译器已经给出了一个错误 只需在父类的构造函数中初始化变量:
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);
}
}
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;
}
}
如果每个敌人的子类需要不同的HitBox
实例,请使用工厂方法模式。这是一个非常简单的例子:
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;
}
}
另一个提示是,如果您不想让null
Hitbox
es创建一个空的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();
}
只需在父类的构造函数中初始化变量:
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);
}
}
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;
}
}
如果每个敌人的子类需要不同的HitBox
实例,请使用工厂方法模式。这是一个非常简单的例子:
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;
}
}
另一个提示是,如果您不想让null
Hitbox
es创建一个空的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();
}
首先,它应该受到保护
,因为子类无权访问私有
字段
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
,而无需担心它。首先,它应该受到保护,因为子类无权访问私有
字段
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
,而不用担心它。由于hbox
字段是从父类继承的,因此应该在父类中初始化它:
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);
}
}
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));
}
}
此示例假定buy
不是抽象类。由于hbox
字段是从父类继承的,因此应在父类处初始化它:
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);
}
}
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));
}
}
本例假设敌方不是抽象类。为什么不将初始值设定项仅放在超类中?为什么不使用hbox=new Hitbox()
在父类的构造函数中?很抱歉,我忘了向Hitbox构造函数调用添加参数。敌方的每个子类都会有一个不同的Hitbox,因此我将在相应的子类中初始化Hitbox。为什么不将初始值设定项仅放在超类中?为什么不使用hbox=new Hitbox()
在父类的构造函数中?很抱歉,我忘了向Hitbox构造函数调用添加参数。敌方的每个子类都会有一个不同的Hitbox,因此我将在相应的子类中初始化Hitbox。@另一种方法是使用工厂方法和依赖项注入,以确保您有一个Hitbox.Factories!当然那太好了,反正我也要实现它。然后,我可以检查一次,一旦创造,如果一切都是好的。多谢各位@potAito检查最后一次编辑以避免null
值出现在您的Hitbox
@potAito另一种方法是使用工厂方法和依赖项注入来确保您有一个Hitbox.Factories!当然那太好了,反正我也要实现它。然后,我可以检查一次,一旦创造,如果一切都是好的。多谢各位@potAito检查最后一次编辑,以避免您的点击框出现null
值