java Java泛型名称冲突,方法未正确覆盖

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2543955/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 21:42:23  来源:igfitidea点击:

Java Generics name clash, method not correctly overridden

javagenerics

提问by Shervin Asgari

I have seen different questions regarding this, but I still find this topic to be very confusing.

我已经看到了与此相关的不同问题,但我仍然觉得这个话题非常令人困惑。

All I want to do, is have an abstract class that implements an interface, and have a class extending this abstract class so that the hard class needs to implement getKommune()and setKommune(Kommune kommune), but not the other method, because that is in the abstract class.

我想要做的就是有一个实现接口的抽象类,并有一个扩展这个抽象类的类,这样硬类需要实现getKommune()and setKommune(Kommune kommune),而不是另一个方法,因为它在抽象类中。

I have the following interface.

我有以下界面。

public interface KommuneFilter {

    <E extends AbstractKommune<?>> void addKommuneFromCurrentUser(E e);

    Kommune getKommune();

    void setKommune(Kommune kommune);
}

And this Abstract class

而这个抽象类

public abstract class AbstractKommune<E extends AbstractKommune<?>> implements KommuneFilter {
    @PrePersist
    void addKommuneFromCurrentUser(E e) {
            Kommune k = e.getKommune();
    }
}

And I want to use it like this

我想像这样使用它

    public class Person extends AbstractKommune<Person> {
        private Kommune kommune;             
        public void setKommune(Kommune kommune) {this.kommune=kommune;}
        public Kommune getKommune() {return kommune;}
    }

However, I get

但是,我得到

Name clash: The method of has the same erasure of type but does not override it

Why isn't it correctly overridden?

为什么它没有被正确覆盖?

UPDATE

Thanks to @Bozho, the solution is this:

更新

感谢@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>

采纳答案by Bozho

I'd suggest making the interface generic, rather than only its method:

我建议使接口通用,而不仅仅是它的方法:

interface KommuneFilter<E extends AbstractKommune<?>> { .. }

And then

接着

public abstract class AbstractKommune<E extends AbstractKommune<?>> 
     implements KommuneFilter<E> 

回答by polygenelubricants

The reason why it's a name clash and not an override is because it isn't. The method specified by the interface is a generic method; your abstract class's attempt to override it isn't.

它是名称冲突而不是覆盖的原因是因为它不是。接口指定的方法为泛型方法;你的抽象类试图覆盖它不是。

A more concise code that reproduces your problem is this:

重现您的问题的更简洁的代码是这样的:

interface I {
    <E> void foo(E e);
}

class C<E> implements I {
    public void foo(E e) { // name clash at compile time!
    }
}

The problem here is that interface Ispecifies that implementors must provide a generic method <E>foo(it can be an <Integer>foo, <Boolean>foo, etc), but say, a C<String>really only has foo(String).

这里的问题是,interface I指定对实现者必须提供一个通用的方法<E>foo(也可以是一个<Integer>foo<Boolean>foo等等),而是说,一个C<String>真正只foo(String)

One way to fix this is to make C.fooa generic method, to properly @Overridethe generic method of interface I:

解决此问题的一种方法是创建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);
    }
}

You can see what this does in the above code: you have a generic type C<E>with a generic method <T>foo(you can use Einstead of T, but that wouldn't change anything -- it's still a generic method with its own type parameter).

你可以在上面的代码中看到它做了什么:你有一个C<E>带有泛型方法的泛型类型<T>foo(你可以使用E代替T,但这不会改变任何东西——它仍然是一个带有自己类型参数的泛型方法)。

Now a C<String>also has <Integer>foo, etc, as specified by interface I.

现在 aC<String>也有<Integer>foo等,如 所指定interface I

If this isn't something that you need, then you probably want to make interface I<E>generic instead:

如果这不是您需要的东西,那么您可能希望改为使用interface I<E>泛型:

interface I<E> {
    void foo(E e);
}

class C<E> implements I<E> {
    @Override public void foo(E e) {
    }
}

Now the type and the method shares the same type parameter (e.g. an I<Boolean>only has a foo(Boolean), a C<String>only has a foo(String)) which is likely what you had originally intended.

现在类型和方法共享相同的类型参数(例如 an I<Boolean>only has a foo(Boolean), a C<String>only has a foo(String))这可能是您最初想要的。