内部类的作用就是增加软件系统的内聚.
一 如果一个对象B只能作为对象A的成员,那么就应该吧这个B作为A的内部类.
下面举一个下订单场景的例子。业务诉求如下:
1,商品如果参加了活动就会根据用户的会员等级8折。
2,商家可以在订单总额上再折扣一定额度。
代码如下:
@RequiredArgsConstructor
@Getter
public class OrderInfo {
private final String orderCode;
private final String shopId;
private final String buyerId;
private final Integer buyerLevel;
private Double discountAmount = 0D;
private final Long orderDate;
private List<OrderGoods> orderGoodsList = new ArrayList<>();
@AllArgsConstructor
@Data
public class OrderGoods{
private final String orderGoodsCode;
private final String skuId;
private Integer num;
private final Double price;
private final Boolean ifAct; //是否有活动
private Double calculateAmount(){
Double tmp = this.price*this.num;
//例如 要根据用户的等级进行折扣;
if(this.ifAct && buyerLevel>=2){ //内部类里面可以非常方便的访问宿主类
tmp = tmp*0.8;
}
return tmp;
}
}
//增加sku到订单中. 如果sku是已存在的,就增加数量并检查价格是否变动,否则就加进去.
public OrderInfo addGoods(String orderGoodsCode, String skuId, Integer num, Double price, Boolean ifAct) {
this.orderGoodsList.stream().filter(x->x.getSkuId().equals(skuId)).findFirst().ifPresentOrElse(
x->{
Asserts.defend(x.getPrice().doubleValue()!=price.doubleValue(),-1001,"sku价格变动!");
x.setNum(num+x.getNum());
},
()->this.orderGoodsList.add( new OrderGoods(orderGoodsCode, skuId, num, price, ifAct))
);
return this;
}
public Double calculateAmountFinal(){
return this.orderGoodsList.parallelStream().mapToDouble(x->x.calculateAmount()).sum() - this.discountAmount; //内部类的私有方法可以在宿主类使用;
}
}
弄成内部类的好处如下:
1 内部类里面可以非常方便的访问宿主类.
2 内部类的私有方法可以在宿主类使用.
3 内部类的构造函数应该在宿主类的方法里面执行.
4 如果要在外面new出这个内部类的话就要设置成public static , 但是如果出现这样的情形,就不适合弄成内部类了.
注意: 内部类要定义成public 才能在外面访问得到它的成员,
二 java 的函数不能返回多个参数 如果弄成Map<String,Object> 在使用的时候又不方便,这时候就可以弄一个内部类;
public class MoreReturn {
private String info = "多返回值的演示说明!";
public void deal(){
//todo 其他的一些业务代码
var rlt = this.getRlt();
if(rlt.code==200){
//todo 成功要干什么
}
else{
//todo 失败要干什么
Asserts.fail(rlt.code,rlt.Msg);
}
}
@AllArgsConstructor
@Data
class TmpRtl {
Integer code;
String Msg;
}
TmpRtl getRlt(){
return new TmpRtl(200,"Success");
}
}
这时候更好的方式是使用record,来代替内部类 充当多返回参数的载体。
public class MoreReturn {
private String info = "多返回值的演示说明!";
public void deal(){
//todo 其他的一些业务代码
var rlt = this.getRlt();
if(rlt.code==200){
//todo 成功要干什么
}
else{
//todo 失败要干什么
Asserts.fail(rlt.code,rlt.msg);
}
}
record TmpRlt(Integer code,String msg){}
TmpRlt getRlt(){
return new TmpRlt(200,"Success");
}
}
三 更神奇的用法在函数里面定义内部类,record,enum 。
public static void main(String[] args) {
enum GoodsField{ price, name, category }
System.out.println(JSONUtil.toJsonPrettyStr(
calculateParam(
List.of(
new QRecord(GoodsField.name,Opt.like,"测试"),
new QRecord(GoodsField.price,Opt.greater_equal,129.9D),
new QRecord(GoodsField.price,Opt.less_equal,299.9D)
)
)
));
}
网友评论