· 前言:这次是由于写自动化代码过程中,需要编写的3个接口参数,C的参数包含B,B的参数包含A,原本的方法是分别新建一个类的方法作为入参,但是由于代码冗余,以及类过多,因此想优化一下,于是碰到问题1.
结构大概是:
A--接口入参组装(对应问题1)
B--接口
C--接口实现(对应其他问题)
问题1. 简化3个接口的输入类,原本是分开3个类编写,目前是在一个类当中通过内部类继承的方式写(3个接口的入参 SCreditRequest、 SWithdrawRequest、 SLoanRequest
@Data
public class base{
@ApiModelProperty(notes = "环境",allowableValues="T1,T2", example = "T2")
public String env;
@ApiModelProperty(notes = "手机号",example="自动生成")
public String phone;
public class SCreditRequest extends BaseRequestParameter{
@Data
public class SWithdrawRequest extends SCreditRequest{
@ApiModelProperty(notes = "借款期数",allowableValues="6,12", example = "6")
public String loanPeriod;
@ApiModelProperty(notes = "借款金额",example = "1000")
public String loanAmount;
@ApiModelProperty(notes = "是否购买",allowableValues="购买,不购买", example = "购买")
public String buyInsurance;
@Data
public class SLoanRequest extends SWithdrawRequest{
public SLoanRequest(SCreditRequest sCreditRequest){
this.env=stageCreditRequest.getEnv();
this.phone=stageCreditRequest.getPhone();
public SLoanRequest(SWithdrawRequest sWithdrawRequest){
this.env=sWithdrawRequest.getEnv();
this.phone=sWithdrawRequest.getPhone();
this.loanPeriod=sWithdrawRequest.getLoanPeriod();
this.loanAmount=sWithdrawRequest.getLoanAmount();
this.buyInsurance=sWithdrawRequest.getBuyInsurance();
@ApiModelProperty(notes = "放款结果",allowableValues = "成功,失败", example = "成功")
private String loanResult;
}复制代码
解决了问题1之后,在接口类调用,具体如下:
@ServiceContract(applicationName = "com.abc.XXX")
public interface SService {
@ApiOperation(value = "开卡",tags = "产品1")
Response sCredit(BaseRequestParameter.SCreditRequest request); //BaseRequestParameter.SCreditRequest是问题1中的内部类复制代码
问题2. 然后在接口实现上碰到具体的父类转子类的问题。
原因是,在实现上,3个接口的前置条件比较相似,但是由于前置条件主要处理入参,而上面3个入参的内部类入参个数不一致,最后一个入参会包含更多参数,因此公共方法入参定义为最多参数的内部类 BaseRequestParameter. SLoanRequest ,但由于其他接口使用的内部类传参是父类,因此会存在父类转子类的问题,报ClassCastExcept异常。
2.1 刚开始查找到的方法,是先把父类引用指向子类,然后再把父类变量强转为子类,强转之后,接口实现里面前置参数处理的公共方法就可以用了。
BaseRequestParameter.SCreditRequest inner=new BaseRequestParameter().new SLoanRequest(); //父类引用指向子类对象
BaseRequestParameter.SLoanRequest in=new BaseRequestParameter().new SLoanRequest();
DataU datau=new DataU(); //一个参数值的实体类
if(inner instanceof BaseRequestParameter.SLoanRequest){ //此判断用于判断A类是否可以转换成B类
in=(BaseRequestParameter.SLoanRequest) inner;
datau=parms.parms(in); //赋值完,可以顺利调用了
}复制代码
上述方法虽然解决了父类到子类的转换,但是并不完全适用于我的脚本,因为我的接口实现,在一开始入参,就传入了父类,也就是已经没有机会再new一个子类,来把父类引用指向子类了。像这样:
@Override
public Response sCredit(BaseRequestParameter.SCreditRequest request) {
******
}复制代码
上述写法参考:https://blog.csdn.net/jin970505/article/details/78619849
2.1 于是继续查找方法,另一个帖子的思路是 将子类实例赋值给父类变量即可 ,于是我修改了一下构造函数,以解决问题,如下,在接口入参的类中,写如下的构造函数:
@Data
public class SLoanRequest extends SWithdrawRequest{
public SLoanRequest(SCreditRequest sCreditRequest){
this.env=sCreditRequest.getEnv();
this.phone=sCreditRequest.getPhone();
public SLoanRequest(SWithdrawRequest sWithdrawRequest){
this.env=sWithdrawRequest.getEnv();
this.phone=sWithdrawRequest.getPhone();
this.loanPeriod=sWithdrawRequest.getLoanPeriod();
this.loanAmount=sWithdrawRequest.getLoanAmount();
this.buyInsurance=sWithdrawRequest.getBuyInsu();
//下面的是这个子类独有的属性,其他父类雷同
@ApiModelProperty(notes = "结果",allowableValues = "成功,失败", example = "成功")
private String Result;
}复制代码
上述写法参考:https://blog.csdn.net/u011630575/article/details/80072241
2.3 然后在同事启发下,发现还有反射的方法,然后从网上找了帖子,关键应该也还是先把父类引用指向子类
上述写法来自:https://blog.csdn.net/u010429286/article/details/78541509