java - 抽象类中的抽象属性
问题描述
我有一个抽象类,其中包含一些使用@Value 设置的配置属性值。我想重用抽象类,但要使用另一组配置属性。问题是,这些属性值已经在抽象类中设置,并且所有具体类都继承了它。
我曾想过:
在抽象类中创建另一组配置值,但这似乎是在创建重复项,但是当将来还有第三组配置值时,这不太可扩展。
将抽象类中配置值的可访问性从私有更改为受保护,并让具体类覆盖它。但我不确定这种覆盖是否良好,因为它似乎会混淆实际配置值是什么。
创建另一个类似于“AbstractService”的抽象类,但使用@Value 注入不同的配置值集。这似乎也造成了重复。
public abstract class AbstractService { @Value("${config1}") private String config1; @Value("${config2}") private String config2; public void serviceMethod() { //using config1 and config 2 values } } public class concreteServiceA extends AbstractService { public void serviceA() { // using serviceMethod in the abstract class } } public class concreteServiceB extends AbstractService { public void serviceB() { // using serviceMethod in the abstract class } }
如果使用构造函数在抽象类中传递所需的参数,并让具体类使用构造函数注入和@Value 来设置这些值,这会是一个好方法吗?虽然如果有很长的配置值列表,这可能无法很好地扩展。
public abstract class AbstractService {
private String config1;
private String config2;
public AbstractService(String config1, String config2) {
this.config1 = config1;
this.config2 = config2;
}
public void serviceMethod() {
//using config1 and config2 values
}
}
public concreteServiceA extends AbstractService {
public concreteServiceA(@Value("${config1}") String config1,
@Value("${config2}") String config2) {
super(config1, config2);
}
public void serviceA() {
//using serviceMethod in the abstract class
}
}
public concreteServiceB extends AbstractService {
public concreteServiceB(@Value("${configB1}") String config1,
@Value("${configB2}") String config2) {
super(config1, config2);
}
public void serviceB() {
//using serviceMethod in the abstract class
}
}
解决方案
您可以使用 setter 注入或(可能更优雅)构造函数注入,如下所示:
public abstract class AbstractService {
protected AbstractService(String config1, String config2) {
this.config1 = config1;
this.config2 = config2;
}
private String config1;
private String config2;
public void serviceMethod() {
//using config1 and config 2 values
}
}
public class ConcreteServiceA extends AbstractService {
public ConcreteServiceA(@Value("${config1a}") String config1, @Value("${config2a}") String config2) {
super(config1, config2);
}
public void serviceA() {
// using serviceMethod in the abstract class
}
}
public class ConcreteServiceB extends AbstractService {
public ConcreteServiceB(@Value("${config1b}") String config1, @Value("${config2b}") String config2) {
super(config1, config2);
}
public void serviceB() {
// using serviceMethod in the abstract class
}
}
但是如果你有很多值,你也可以使用 setter 注入并覆盖每个子类中的 setter。或者您仍然可以使用构造函数注入,但传递一个包含配置的容器类,如下所示:
public class ServiceConfig {
private String config1;
private String config2;
// getters, setters and more properties
}
然后像这样通过
public abstract class AbstractService {
private ServiceConfig config;
protected AbstractService(ServiceConfig config) {
this.config = config;
}
}
public class ConcreteServiceA extends AbstractService {
public ConcreteServiceA(@Value("${configA}") ServiceConfig config) {
super(config);
}
}
推荐阅读
- android - 在 Android 应用程序的 ViewGroup 的“onInterceptTouchEvent”方法中,ACTION_MOVE 事件能否在 ACTION_DOWN 事件之前到达?
- c++ - 在 C++ 中使用 while 循环查找一组数字中的最小值的程序
- html - 视频 I 帧在移动浏览器上无法正常工作
- r - 如何使用 R 将每小时乘客 OD 数据传输到 od 矩阵
- android - 安装失败并显示消息无法提交安装会话
- python - 子集多索引列
- kubernetes - 当节点在 Kubernetes 上出现故障时如何运行脚本?
- python - Python CGI 脚本正在下载而不是运行
- javascript - 使用jquery在表格行的div中显示/隐藏图标
- c# - TestStack.White 不能点击菜单栏项目?