【发布时间】:2020-04-27 14:18:32
【问题描述】:
当子类之间没有共同的实现时,我总是使用接口。但是JAXB中内置的XmlAdapter是一个抽象类,ALL里面的方法都是抽象的,为什么不做成接口而不是抽象类呢?应该是有原因的。
【问题讨论】:
标签: java oop interface jaxb abstract-class
当子类之间没有共同的实现时,我总是使用接口。但是JAXB中内置的XmlAdapter是一个抽象类,ALL里面的方法都是抽象的,为什么不做成接口而不是抽象类呢?应该是有原因的。
【问题讨论】:
标签: java oop interface jaxb abstract-class
XmlAdapter 定义了两个抽象方法,以及一个默认的无参数保护构造函数。
Unmarshallers 和Marshallers 使用默认构造函数创建XmlAdapter 的实例(除非提供了setAdapter 的实例)。
我最初的想法是,原因是确保Marshaller 和Unmarshaller 始终有一个默认的无参数构造函数,但正如你所说,如果XmlAdapter 的子类声明了一个非无参数构造函数,这将使XmlAdapter 的默认构造函数不可见。事实上,XmlAdapter 实现添加了带 args 的构造函数,但没有提供无参数构造函数,这会导致 Marshall/Unmarshall 操作失败,除非实例提供了 setAdapter 方法。
因此,没有实际理由使用抽象类来代替当前实现的接口。
我的猜测是这是一个设计决策,因为从进化的角度来看,使用抽象类最适合。例如,如果在构造函数中需要某种常见的初始化,它可以在现在为空的构造函数上实现。或者,如果 XmlAdapter 中需要一个方法来编组对象列表,则可以使用以下方式实现:
public List<ValueType> marshalList(List<BoundType> list) throws Exception {
List<ValueType> result = new ArrayList<>();
for (BoundType b: list) {
result.add(marshal(b));
}
return result;
}
并且 JAXB 内部类可以使用此方法而无需修改任何适配器实现。
【讨论】:
no-arg 构造函数,这不会使默认的无参数构造函数不可见吗?