Java重写抽象泛型函数时调用对象方法的编译错误问题
解决Java泛型方法重写时编译器无法识别子类方法的问题
嘿,这个问题我之前也踩过坑!本质是你把子类泛型参数的名字和实际定义的OtherClass类搞混了,编译器根本没把它们当成一回事儿,所以才会报错找不到方法。
问题根源分析
你父类A里的foo是一个无边界的方法级泛型:
public abstract class A { public abstract <E> void foo(E e); }
到了子类B,你写的<OtherClass>只是泛型参数的占位符名字,和你自己定义的OtherClass类完全无关——编译器会把它当成和父类<E>一样的任意类型,自然不知道这个类型有someOtherClassMethod()方法。
三种可行的解决方案
方案1:把泛型移到类级别(最推荐)
如果父类的foo方法本来就应该处理特定类型的对象,那把泛型定义在类上更合理,这样子类可以明确指定具体类型:
修改父类A:
public abstract class A<E> { public abstract void foo(E e); }
子类B继承时指定泛型类型:
public class B extends A<OtherClass> { @Override public void foo(OtherClass oc) { oc.someOtherClassMethod(); // 编译器现在能识别这个方法了! } }
方案2:给泛型方法加边界约束
如果父类必须保留方法级泛型,但只接受拥有someOtherClassMethod()的类型,可以定义一个接口来约束泛型:
第一步:定义约束接口
public interface HasSomeMethod { void someOtherClassMethod(); }
第二步:让OtherClass实现这个接口
public class OtherClass implements HasSomeMethod { @Override public void someOtherClassMethod() { // 这里写你的方法实现 } }
第三步:修改父类和子类的泛型方法
public abstract class A { // 泛型E必须是HasSomeMethod的子类/实现类 public abstract <E extends HasSomeMethod> void foo(E e); } public class B extends A { @Override public <E extends HasSomeMethod> void foo(E e) { e.someOtherClassMethod(); // 编译器能识别方法了 } }
方案3:直接指定具体类型(不推荐,失去泛型优势)
如果就是想让子类B的foo只处理OtherClass,可以把父类的泛型方法改成接受Object,子类重写时强转:
修改父类A:
public abstract class A { public abstract void foo(Object e); }
子类B强转类型:
public class B extends A { @Override public void foo(Object e) { // 最好先做类型检查,避免ClassCastException if (e instanceof OtherClass) { ((OtherClass) e).someOtherClassMethod(); } } }
这种方式的缺点是失去了编译时的类型安全,不推荐优先使用。
内容的提问来源于stack exchange,提问作者mcfb
相关产品推荐
相关产品推荐

