Java中如何更简洁地访问父类泛型ArrayList内的子类独有属性和方法
可行的优化方案
因为你明确要求必须使用ArrayList<Student>存储子类实例,所以可以从以下三个方向优化,避免随处写强制类型转换代码:
方案1:利用多态特性在父类定义公共方法
在父类Student中定义子类独有功能的抽象/默认实现,子类重写对应方法,调用时直接用父类引用触发多态,完全不需要强转:
// 父类新增默认实现 public class Student { // 原有逻辑保持不变 public Integer getAss1() { // 不存在该属性的子类可返回null,或抛出UnsupportedOperationException return null; } } // 本科生子类重写方法 public class UndergraduateStudent extends Student { // 原有unit属性等逻辑保持不变 @Override public Integer getAss1() { return this.unit.getAss1(); } } // 调用代码无需强转,可读性大幅提升 std_list.get(0).getAss1();
该方案适合子类独有的公开方法数量较少的场景,完全符合面向对象设计规范。
方案2:封装强转逻辑为公共方法
把重复的类型校验、强转逻辑抽成单独的工具方法,业务代码直接调用即可,同时还能提前做类型合法性校验,避免运行时类型转换异常:
// 封装抽取公共获取方法 private UndergraduateStudent getUndergraduateByIndex(int index) { Student target = std_list.get(index); if (target instanceof UndergraduateStudent) { return (UndergraduateStudent) target; } throw new IllegalArgumentException("指定索引下的学生不是本科生类型"); } // 业务侧调用代码 getUndergraduateByIndex(0).getUnit().getAss1();
该方案适合需要频繁从列表中获取本科生实例的场景,减少重复代码的同时统一处理类型异常。
方案3:使用JDK16+的instanceof模式匹配语法
如果你的项目JDK版本在16及以上,可以直接用模式匹配语法简化强转代码,无需显式写强制类型转换语句:
Student target = std_list.get(0); if (target instanceof UndergraduateStudent ugStudent) { // 直接使用自动转换后的ugStudent变量 ugStudent.unit.getAss1(); }
该方案适合列表中混存多种Student子类、需要频繁做类型判断的场景,代码简洁易读。
内容的提问来源于stack exchange,提问作者Zileith
相关产品推荐
相关产品推荐

