能否设置必填属性(抽象属性)?子类定义属性的代码写法是否可行?
嗨,我来帮你理清这两个Java抽象类相关的问题~
问题1:能否设置必填的抽象属性?
首先得明确:Java里并没有“抽象属性(字段)”这个语法概念,你写的protected abstract Action action;是不符合Java语法的——字段(成员变量)不能被声明为abstract,只有类和方法可以用abstract修饰。
如果想要实现“所有子类必须提供某个属性”的效果,我们通常用抽象方法来间接实现,比如定义一个返回该属性的抽象方法,强制子类必须实现它:
abstract class AbstractSuperClass { protected Entity entity; // 用抽象方法强制子类提供Action实例 protected abstract Action getAction(); public AbstractSuperClass(Entity entity) { this.entity = entity; } public void operate() { // 通过抽象方法获取Action实例 this.getAction().doVoidMethod(); } }
这样一来,所有子类都必须实现getAction()方法,相当于强制子类提供了这个“必填属性”的内容。
问题2:子类定义属性的代码是否可行?
你当前写的代码首先会编译失败,因为父类里的protected abstract Action action;是非法语法(字段不能是抽象的)。
如果我们调整父类的写法,把action改成普通的protected字段,再看子类的赋值逻辑:
abstract class AbstractSuperClass { protected Entity entity; protected Action action; // 改为普通字段 public AbstractSuperClass(Entity entity) { this.entity = entity; } public void operate() { this.action.doVoidMethod(); } } public class SubClass extends AbstractSuperClass { public SubClass(Entity entity) { super(entity); this.action = new Action(); // 子类构造时赋值 } }
这段代码语法上是可以通过的,但存在潜在的空指针风险:如果父类的构造器里调用了operate()方法,或者在子类构造完成前就有人调用operate(),那action还没被赋值,就会抛出NullPointerException。
更稳妥的做法,要么在父类构造器里就要求传入Action(强制子类初始化时提供):
abstract class AbstractSuperClass { protected Entity entity; protected Action action; // 父类构造器要求同时传入Entity和Action public AbstractSuperClass(Entity entity, Action action) { this.entity = entity; this.action = action; } public void operate() { this.action.doVoidMethod(); } } public class SubClass extends AbstractSuperClass { public SubClass(Entity entity) { // 子类构造时传入Action实例 super(entity, new Action()); } }
要么就用前面问题1提到的抽象方法方案,从根本上避免空指针问题,同时强制子类提供Action实例。
内容的提问来源于stack exchange,提问作者user3310334
相关产品推荐
相关产品推荐

