名称冲突 - 在方法参数通用中具有相同的抹消,但两者都没有覆盖。

7

我已经阅读了有关“名称冲突 - 擦除相同但都不覆盖”的所有问题和答案,但仍然不明白如何解决这个问题。因此,

@Dependent
public class SimpleFoo {}

@Dependent
public class AdvancedFoo extends SimpleFoo {}

@Dependent
public class Parent {

    @Inject
    protected void setFooInstance(Instance<? extends SimpleFoo> instance) {}
}

@Dependent
public class Child extends Parent {

    @Override
    protected void setFooInstance(Instance<AdvancedFoo> instance) {} //Error here
}

如何解决这个问题?
3个回答

6
问题在于Child类声明了覆盖以下方法:
@Override
protected void setFooInstance(Instance<AdvancedFoo> instance) {} //Error here

但是Parent类声明了一个具有特定签名的setFooInstance方法:

protected void setFooInstance(Instance<? extends SimpleFoo> instance) {}

1)可以通过以下方式覆盖 Child 类:

public class Child extends Parent {

    @Override
    protected void setFooInstance(Instance<? extends SimpleFoo> instance){... }
}

或者2)其他方式:如果你想强制子类中被覆盖的方法声明一个特定的SimpleFoo,可以将Parent类作为一个泛型类参数化,参数类型为SimpleFoo或其子类:

@Dependent
public class Parent <T extends SimpleFoo>{

    @Inject
    protected void setFooInstance(Instance<T> instance) {...}
}

现在可以声明 Child 类:
@Dependent
public class Child extends Parent<AdvancedFoo> {

    @Override
    protected void setFooInstance(Instance<AdvancedFoo> instance) {...}  
}

1
这不是一个明显的擦除,只是一个明显的签名。擦除直到运行时才变得相关,而这是一个编译错误。 - Dawood ibn Kareem
没错。编译错误显示它们具有相同的擦除。你的答案说它们是不同的擦除。它们不能同时正确。 - Dawood ibn Kareem
@DawoodibnKareem 我认为现在一切都没问题了,我已经删除了我的评论。 - aschoerk

2

如果你将Child转换为泛型类,那么你可以做任何你想做的事情。然后让Parent扩展特定类型的Child,如下所示。

public class Child<T extends SimpleFoo> {
    protected void setFooInstance(Instance<T> instance) {}
}

public class Parent extends Child<AdvancedFoo> {
    @Override
    protected void setFooInstance(Instance<AdvancedFoo> instance) {}
}

顺便提一下,你的命名有点令人困惑。大多数人会期望Child继承Parent,而不是反过来。


1
我已经给你一个正确的答案来回答你最初提出的问题。也就是说,我已经帮助了你。你不觉得要求我为你做更多的工作是不合理的吗?只是因为你改变了问题?@Pavel_K - Dawood ibn Kareem

1
您希望Parent.setFooInstance可被所有可能的Instance<SimpleFoo>的后代调用。但对于Child类型的对象,这种情况不成立,因为您只能将Instance<Advanced>作为参数。因此无法以这种方式进行重写。否则,只知道Parent类的代码调用setFooInstance时,可能会使用错误类型的对象进行调用。 因此,您可以将Parent方法的参数限制为AdvancedFoo,或允许Child.setFooInstance也处理SimpleFoo的后代。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接