Java多态场景下不使用强制类型转换的实现方案咨询
解决方案
你可以通过以下三种常见的实现方案去掉强制类型转换:
方案1:父类定义公共业务方法,子类重写实现差异化逻辑
这是最符合面向对象多态特性的实现方式:在父类A中定义统一的属性设置方法,子类B重写该方法加入自身属性的设置逻辑,调用时直接用父类引用调用该方法即可,会自动根据实际实例类型执行对应逻辑。
代码修改如下:
父类A修改
class A{ int a; public int getA(){ return a; } public void setA(int a){ this.a=a; } // 新增统一的属性设置方法,父类默认实现只设置a public void setParams(int aValue){ setA(aValue); } }
子类B修改
class B extends A{ int b; public int getB(){ return b; } public void setB(int b){ this.b=b; } // 重写设置方法,同时设置a和b @Override public void setParams(int aValue) { super.setParams(aValue); setB(4); // 如果b的值需要动态传入,也可以给方法加第二个int参数接收b的值 } }
主类修改
class HelloWorld { public static void main(String[] args) { A aa; if(runtime condition) { aa= new B(); } else{ aa= new A(); } // 直接调用统一方法,无需判断类型、无需强转 aa.setParams(3); } }
方案2:封装对象创建逻辑,分支内用具体类型接收实例
如果不想修改父类和子类的原有结构,可以把对象创建和初始化的逻辑收敛在条件分支内部,分支内用具体类型的变量接收实例,完成所有属性设置后再赋值给父类引用:
class HelloWorld { public static void main(String[] args) { A aa; if(runtime condition) { B b = new B(); b.setA(3); b.setB(4); aa = b; } else{ A a = new A(); a.setA(3); aa = a; } } }
这种方案不需要修改原有类的结构,适合无法修改父类/子类源代码的场景。
可选方案(JDK 16+):instanceof模式匹配
如果你使用JDK16及以上版本,可以用instanceof的模式匹配语法避免显式强转:
class HelloWorld { public static void main(String[] args) { A aa; if(runtime condition) { aa= new B(); aa.setA(3); // 匹配成功后直接用变量b接收转换后的实例,不需要手动强转 if(aa instanceof B b){ b.setB(4); } } else{ aa= new A(); aa.setA(3); } } }
内容的提问来源于stack exchange,提问作者Kuldeep Singh
相关产品推荐
相关产品推荐

