我知道 - 基于这里的不同问题:
在多重继承的情况下(Carproperty = "carType"
。
但是我有不同的场景现在对我有用 - 这是否也不支持? - 我还需要使用两个鉴别器的场景,但不在“继承链”中:
第一级:
carType
(重要提示:奥迪有场private ColorDiscriminator color;
)
public enum CarType {
AUDI, TOYOTA;
public static final String AUDI_STR = "AUDI";
public static final String TOYOTA_STR = "TOYOTA";
}
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "carType",
visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Audi.class, name = CarType.AUDI_STR),
@JsonSubTypes.Type(value = Toyota.class, name = CarType.TOYOTA_STR)
})
public abstract class CarDiscriminator {
private CarType carType;
public CarType getCarType () {
return carType;
}
public void setCarType (CarType carType) {
this.carType = carType;
}
}
@JsonTypeName(CarType.AUDI_STR )
public class Audi extends CarDiscriminator {
private ColorDiscriminator color;
// ommited
}
@JsonTypeName(CarType.TOYOTA_STR)
public class Toyota extends CarDiscriminator {
// ommited
}
第二级:
colorType
public enum ColorType {
BLUE, RED;
public static final String BLUE_STR = "BLUE";
public static final String RED_STR = "RED";
}
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "colorType",
visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Blue.class, name = ColorType.BLUE_STR),
@JsonSubTypes.Type(value = Red.class, name = ColorType.RED_STR)
})
public abstract class ColorDiscriminator {
private ColorType colorType;
public ColorType getColorType () {
return colorType;
}
public void setColorType (ColorType colorType) {
this.colorType = colorType;
}
}
@JsonTypeName(ColorType.BLUE_STR)
public class Blue extends ColorDiscriminator {
// ommited
}
@JsonTypeName(ColorType.RED_STR)
public class Red extends ColorDiscriminator {
// ommited
}
在生成的 swagger json(和 ui)定义中,我首先可以正确看到
oneOf
carType:Audi
| Toyota
。但第二个colorType
不是。生成的 json 甚至不包含 Blue
也不包含 Red
对象定义。
您提供的两个链接都表示不支持多重继承,并且根据他们的官方 GitHub 存储库,已经说过几次没有计划。
这不受支持,并且没有计划朝这个方向扩展类型解析。
对多级分辨率的支持不存在,也没有计划。因此定义的链接将不起作用。
不支持并且没有计划支持它。不要假设这将会实现来设计您的系统。
顺便说一句,不要用仅支持单继承的语言设计具有多重继承的类。此外,您正在建模的对象(汽车模型和颜色)不共享继承关系。
继承是一种规范关系,我们从更广泛的类型(基类)到更具体的类型(派生类)。派生类仍然具有与基类相同的属性和行为,但它通常会添加或重新定义以将其专门用于其旨在解决的问题类。在继承中,基类的实例也称为基类的实例。这种关系通常被称为 is-a。
is-a的一个典型例子是
Vehicle > Car > Audi
,其中,由于汽车是一辆车辆,所以奥迪是一辆汽车和车辆。在您的代码中不能说同样的事情,您试图将不存在的多重继承关系映射到 json 中。仅仅因为奥迪是蓝色的,并不意味着它是一种颜色。那只是一个财产。如果两者之间确实存在继承关系,那么它们也应该共享相同的属性和行为,但事实并非如此。一般来说,在设计继承时,我们应该问自己“is X a Y?”。如果答案是肯定的,那么这两个对象实际上具有 is-a 关系,并且应该这样设计;否则,如果答案是否定的,我们就不应该强制两者之间继承。
在您的情况下,更好的实现是下面的,其中
ColorType
被保留,以防您只需要一组预定义的颜色。
public enum ColorType {
BLUE("BLUE"), RED("RED");
private String color;
ColorType(String color){
this.color = color;
}
public String getColor() {
return color;
}
}
public class Car {
private String brand;
private String model;
private ColorType color;
// ... rest of the implementation ...
}
相反,如果由于某种原因您需要在数据模型中的汽车之间进行实际分离,您可以这样编写。在这里,您仍在描述实际的继承关系,其中颜色被视为属性,并且管理奥迪的不同实例、丰田的不同实例等对您来说很重要。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "brand")
@JsonSubTypes({
@JsonSubTypes.Type(value = Audi.class, name = "audi"),
@JsonSubTypes.Type(value = Toyota.class, name = "toyota")
})
public abstract class Car {
protected ColorType color;
//common car properties
// some abstract methods that will be specialized in the derived classes
public Car() {
}
public Car(ColorType color) {
this.color = color;
}
public ColorType getColor() {
return color;
}
public void setColor(ColorType color) {
this.color = color;
}
}
public class Audi extends Car {
public Audi() {
}
public Audi(ColorType color) {
super(color);
}
//specialized properties that only Audi cars have
//specialized behavior
}
public class Toyota extends Car {
public Toyota() {
}
public Toyota(ColorType color) {
super(color);
}
//specialized properties that only Toyota cars have
//specialized behavior
}
这里还有 OneCompiler
的代码演示