如何强制子类在java中设置变量?
2022-09-01 15:24:46
我有一个类,它定义了给定屏幕的所有基本参数。从这里开始,应用程序中的每个屏幕都是它的子类。我需要每个屏幕(即子类)在其实现中设置变量的值(即,每个屏幕必须定义它在导航树中的级别)。
此外,理想情况下,这个变量应该是在子类中设置它的时候(我意识到这可能是不可能的)。final
最好的方法是什么?有没有办法在Java中正确实施这种类型的行为?
我有一个类,它定义了给定屏幕的所有基本参数。从这里开始,应用程序中的每个屏幕都是它的子类。我需要每个屏幕(即子类)在其实现中设置变量的值(即,每个屏幕必须定义它在导航树中的级别)。
此外,理想情况下,这个变量应该是在子类中设置它的时候(我意识到这可能是不可能的)。final
最好的方法是什么?有没有办法在Java中正确实施这种类型的行为?
@pst的评论导致了这个解决方案。
这不能用变量来完成。但是抽象类可以要求实现特定方法:此方法可以返回适用的值
通过声明函数来设置或返回变量,您可以强制任何子类正确实现它。abstract
接下来,该函数必须由外部类的每个子类调用。这意味着它必须在外部类中的某个位置完成。这可以在外部类的无参数构造函数中完成,而不必担心子类调用:super
注: 如果构造函数未显式调用超类构造函数,Java 编译器会自动插入对超类的无参数构造函数的调用。如果超类没有无参数构造函数,您将收到编译时错误。对象确实有这样的构造函数,所以如果对象是唯一的超类,那就没有问题了。(Java docs: Super)
基于此,此解决方案将保持并正确强制设置变量,只要:
代码:
超类:
public abstract class SuperClass {
// Variable all inner classes must set
static int myVar = 0;
public SuperClass() {
myVar = giveValue();
}
public abstract int giveValue();
}
亚纲:
public class SubClass extends SuperClass {
@Override
public int giveValue() {
return 5; // individual value for the subclass
}
}
与其强制子类实例初始化字段,不如遵循组合策略,让父类构造函数采用一个参数来实现一个接口,该接口提供您希望初始化的字段。
class Screen {
final Configuration config;
Screen(Configuration config) {
this.config = config;
}
// or
Screen(ConfigFactory configFactory) {
this.config = configFactory.make();
}
}
interface ConfigFactory {
Configuration make();
}
我提醒不要要求子类实例初始化配置,例如使用抽象方法实现。父类构造函数中的赋值在子类实例初始化之前发生,从而隐式地使配置的正确计算成为静态的。
如果计算不是静态的,则存在以下开发人员(或者如果您的内存不完美,则为您自己的)的空引用或 NullPointerExceptions 的风险。让您的协作者(和您自己)更轻松,并使约束明确。