Java中子类重写父类方法时如何将返回值类型设为子类类型
错误原因说明
- 初始代码编译报错:子类B重写的
foo()方法声明返回值为B类型,但super.foo()调用父类方法返回的是A类型实例,父类类型无法隐式转换为子类类型,因此编译不通过。 - 添加强转后运行报错:
super.foo()返回的本质是A类的实例,Java不支持父类实例强制转换为子类类型,运行时会抛出ClassCastException。
正确实现方式
Java 5及以上版本支持协变返回类型,只要保证重写方法返回的实例确实是B类的对象即可,基础实现代码如下:
class A { A foo() { return new A(); } } class B extends A { @Override B foo() { return new B(); } }
如果需要复用父类foo()方法的通用逻辑,可以调整父类结构,将实例创建逻辑抽取为可重写的独立方法,实现方案如下:
class A { // 抽取实例创建逻辑,允许子类重写 protected A newInstance() { return new A(); } A foo() { // 此处可以写所有子类通用的逻辑 A instance = newInstance(); // 其他通用操作 return instance; } } class B extends A { @Override protected B newInstance() { return new B(); } @Override B foo() { // 此时super.foo()返回的实际是B类实例,强转不会出现运行时错误 return (B) super.foo(); } }
内容的提问来源于stack exchange,提问作者tony
相关产品推荐
相关产品推荐

