如何基于父类Instancio Model配置创建子类Model?
基于Instancio父类Model创建子类Model的正确实现
你遇到的错误是因为写法逻辑有误:set(Select.fields().ofType(Pet.class), Instancio.create(defaultPetModel()))这种方式是试图给类型为Pet的字段赋值,但Dog本身是Pet的子类,不是一个字段,所以选择器匹配不到任何目标,才会报“未使用的选择器”错误。而且直接创建Pet实例赋值也违背了Model作为配置模板的初衷。
其实Instancio完全支持基于父类Model创建子类Model,用merge()方法就能轻松实现,下面是两种可行的方案:
方案一:复用父类Model的完整配置
直接通过merge()方法将父类Model的配置合并到子类Model中,Instancio会自动处理继承关系,把父类的字段配置应用到子类实例上:
import org.instancio.Instancio; import org.instancio.Model; import org.instancio.Select; import org.junit.jupiter.api.Test; public class ModelInheritance { @Test void modelTest() { Dog dog = Instancio.create(defaultDogModel()); System.out.println(dog.getSound()); // 输出 Bark System.out.println(dog.getName()); // 输出 Punky System.out.println(dog.getColor()); // 输出 White } private Model<Dog> defaultDogModel() { return Instancio.of(Dog.class) .merge(defaultPetModel()) // 复用Pet的Model配置 .set(Select.field(Dog::getSound), "Bark") .toModel(); } private Model<Pet> defaultPetModel() { return Instancio.of(Pet.class) .set(Select.field(Pet::getName), "Punky") .set(Select.field(Pet::getColor), "White") .toModel(); } } abstract class Pet { String name; String color; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } } class Dog extends Pet { String sound; public String getSound() { return sound; } public void setSound(String sound) { this.sound = sound; } }
方案二:单独配置父类继承的字段
如果不需要复用父类的完整Model,也可以直接通过选择器指定父类的字段,因为子类继承了这些字段,选择器会正确匹配:
// 修改defaultDogModel方法即可 private Model<Dog> defaultDogModel() { return Instancio.of(Dog.class) .set(Select.field(Pet::getName), "Punky") .set(Select.field(Pet::getColor), "White") .set(Select.field(Dog::getSound), "Bark") .toModel(); }
这两种方法都能解决你遇到的问题,其中方案一更符合你“复用父类Model”的需求。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

