Java中无法实例化接口或抽象类时如何将其作为实体类字段类型
解决方案
你完全不需要为两个实现类单独创建对应字段,你对「字段声明为接口类型」的用法存在误解:字段声明为接口类型仅代表该字段可以接收所有该接口的实现类实例,不需要你在DebitAccount类中实例化这个接口,实例化逻辑完全可以放在给字段赋值的业务代码中,这正是Java多态的典型使用场景。
具体修改方案
直接将clientId字段替换为Client类型即可,修改后的代码如下:
package com.bankapp.bankwebapplication.models; import javax.persistence.Entity; import javax.persistence.Id; // 注意导入Client接口的对应包 import com.bankapp.bankwebapplication.models.Client; @Entity public class DebitAccount implements Account { @Id private Long id; public Long getId() { return id; } public void setId(Long id) { this.id = id; } // 直接声明为Client接口类型即可 private Client client; public Client getClient() { return client; } public void setClient(Client client) { this.client = client; } private Long amountOfMoney; public Long getAmountOfMoney() { return amountOfMoney; } public void setAmountOfMoney(Long amountOfMoney) { this.amountOfMoney = amountOfMoney; } }
后续使用示例
你在业务逻辑中给client字段赋值时,直接传入它的实现类实例即可:
// 绑定个人客户 DebitAccount personAccount = new DebitAccount(); personAccount.setClient(new PersonClient()); // 绑定企业客户 DebitAccount companyAccount = new DebitAccount(); companyAccount.setClient(new CompanyClient());
如果需要区分当前账户关联的客户类型,可以用instanceof判断,也可以直接调用Client接口中定义的统一方法,由不同实现类自行处理逻辑,不需要强转类型:
// 直接调用接口定义的统一方法,自动适配实现类逻辑 personAccount.getClient().sendNotification("账户变动提醒");
特殊场景适配
如果你的场景需要对该字段做序列化/反序列化(比如前后端参数传递、缓存存储),可以用对应框架的多态注解指定类型鉴别规则,比如Jackson序列化可以加如下注解:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "clientType") @JsonSubTypes({ @JsonSubTypes.Type(value = PersonClient.class, name = "person"), @JsonSubTypes.Type(value = CompanyClient.class, name = "company") }) private Client client;
这样序列化和反序列化时都能自动识别具体的实现类类型,不会出现无法实例化接口的报错。
内容的提问来源于stack exchange,提问作者dokichan
相关产品推荐
相关产品推荐

