我已经看到了不同的问题,但我仍然觉得这个话题非常混乱。
我想要做的是,有一个实现接口的抽象类,并且有一个扩展这个抽象类的类,以便硬类需要实现getKommune()
和setKommune(Kommune kommune)
,但不是其他方法,因为那是在抽象类中。
我有以下界面。
public interface KommuneFilter {
<E extends AbstractKommune<?>> void addKommuneFromCurrentUser(E e);
Kommune getKommune();
void setKommune(Kommune kommune);
}
这个抽象类
public abstract class AbstractKommune<E extends AbstractKommune<?>> implements KommuneFilter {
@PrePersist
void addKommuneFromCurrentUser(E e) {
Kommune k = e.getKommune();
}
}
我想像这样使用它
public class Person extends AbstractKommune<Person> {
private Kommune kommune;
public void setKommune(Kommune kommune) {this.kommune=kommune;}
public Kommune getKommune() {return kommune;}
}
但是,我得到了
Name clash: The method of has the same erasure of type but does not override it
为什么不正确覆盖?
更新
感谢@Bozho,解决方案是:
public interface KommuneFilter<E extends AbstractKommune<?>> {
public void addKommuneFromCurrentUser(E e);
}
public abstract class AbstractKommune<E extends AbstractKommune<?>> implements KommuneFilter<E>
public class Person extends AbstractKommune<Person>
答案 0 :(得分:5)
我建议将界面设为通用的,而不仅仅是它的方法:
interface KommuneFilter<E extends AbstractKommune<?>> { .. }
然后
public abstract class AbstractKommune<E extends AbstractKommune<?>>
implements KommuneFilter<E>
答案 1 :(得分:2)
它之所以是名字冲突而不是覆盖是因为它不是。接口指定的方法是通用方法;你的抽象类试图覆盖它不是。
更简洁的代码可以重现您的问题:
interface I {
<E> void foo(E e);
}
class C<E> implements I {
public void foo(E e) { // name clash at compile time!
}
}
这里的问题是interface I
指定实现者必须提供通用方法<E>foo
(它可以是<Integer>foo
,<Boolean>foo
等,但是,例如, C<String>
实际上只有foo(String)
。
解决此问题的一种方法是使C.foo
成为通用方法,以正确@Override
interface I
的通用方法:
interface I {
<E> void foo(E e);
}
class C<E> implements I {
@Override public <T> void foo(T t) {
}
public static void main(String args[]) {
C<String> o = new C<String>();
o.<Integer>foo(0);
o.<Boolean>foo(false);
}
}
您可以在上面的代码中看到它的作用:您的通用类型C<E>
包含通用方法<T>foo
(您可以使用E
代替T
,但这不会改变任何东西 - 它仍然是一个带有自己的类型参数的泛型方法。)
现在,C<String>
也有<Integer>foo
等,由interface I
指定。
如果这不是您需要的,那么您可能希望改为interface I<E>
通用:
interface I<E> {
void foo(E e);
}
class C<E> implements I<E> {
@Override public void foo(E e) {
}
}
现在类型和方法共享相同的类型参数(例如,I<Boolean>
只有foo(Boolean)
,C<String>
只有foo(String)
,这很可能是什么你最初想要的。