[英]Name Clash, override fail, on a class implementing two interfaces with same erasure
I am creating a class that overrides a method signature whose erasure is identical between 2 implemented interfaces, but with a minor difference in regards of the generic type (one is a method-inferred type, the other an inferred-class type). 我正在创建一个覆盖方法签名的类,其擦除在两个实现的接口之间是相同的,但在泛型类型方面有一些细微的差别(一个是方法推断类型,另一个是推断类类型)。 I am looking for a neat solution.
我正在寻找一个简洁的解决方案。 I CAN ONLY edit the inherited class, not the original legacy interfaces.
我只能编辑继承的类,而不是原始的遗留接口。
To show the case, I made up an abstract sample, to understand the problem: 为了说明这个案例,我编写了一个抽象样本,以了解问题:
I got a Developer legacy parent class: 我有一个开发人员遗留父类:
public class Developer<C>{
Rate<C> getRate(Taxes<C> tax){ /*...*/ }
}
I also got a Rentable legacy interface, with an almost identical signature 我还有一个Rentable传统界面,签名几乎相同
public interface Rentable {
<C> Rate<C> getRate(Taxes<C> taxes);
}
As a developer is not rentable, in my model, I create an special developer which is both a Developer, and Rentable material. 由于开发人员不可出租,在我的模型中,我创建了一个特殊的开发人员,它既是Developer,也是Rentable材料。
public class OutsourcableDeveloper<C>
extends Developer<C>
implements Rentable{
@Override
public Rate<C> getRate(Taxes<C> taxes){ /*...*/}
}
and then I got the infamous 然后我得到了臭名昭着的
Name clash: The method getRate(Developer.Taxes) of type OutsourcableDeveloper has the same erasure as getRate(Developer.Taxes) of type Rentable but does not override it
名称冲突:类型为OutsourcableDeveloper的方法getRate(Developer.Taxes)与类型为Rentable的getRate(Developer.Taxes)具有相同的擦除功能但不覆盖它
How can I get rid of it, so OutsourcableDeveloper.getRate() hides both Developer and Rentable. 我怎样才能摆脱它,所以OutsourcableDeveloper.getRate()隐藏了Developer和Rentable。 getRate()?
的getRate()?
It seems a bit illogical to fail a common override but then disallowing extending both signatures as the erasures are equal. 失败一个普通的覆盖似乎有点不合逻辑,但随后删除两个签名,因为删除是相同的。
Does it really matters so much the fact that one of the supertypes infers type from de method and the other from the class specially when I'm not going to call any super in my implementation? 真的很重要的是,其中一个超类型推断出来自de方法的类型,另一个来自类,特别是当我不打算在我的实现中调用任何超级时? Is there perhaps a trick to overcome the issue given this simplification?
鉴于这种简化,是否有一个技巧可以克服这个问题?
EDIT: I opened a more abstract, less solution-oriented to my actual problem, question to discuss the inheritance design problem which I believe is the correlated essence of the actual issue I am having: Why can't I extend an interface "generic method" and narrow its type to my inherited interface "class generic"? 编辑:我打开了一个更抽象,更少解决方案面向我的实际问题,讨论继承设计问题的问题,我认为这是我遇到的实际问题的相关本质: 为什么我不能扩展接口“泛型方法“并将其类型缩小为我继承的接口”class generic“?
EDIT2: Previous question lead me to the answer posted here 编辑2:上一个问题引导我到这里发布的答案
Well they are actually not equal. 那么他们实际上是不平等的。 Because any Rentable-Instance allows any typeparameter T to be given, while the OutsourcableDeveloper restricts it.
因为任何Rentable-Instance允许给出任何类型参数T,而OutsourcableDeveloper限制它。
Of course you can assume that in your case it is easy to use the 当然你可以假设在你的情况下很容易使用
<C> Rate<C> getRate(Taxes<C> taxes);
Version of the interface. 界面版本。 But expect how confused a developer could be, if he wants to subclass
OutsourceableDeveloper
. 但是如果他想要将
OutsourceableDeveloper
子类化,那么预计开发人员会有多么困惑。 From the definition of Developer he can assume that the Method getRate is fixed to C
but actually it can suddenly take any value. 根据Developer的定义,他可以假设Method getRate固定为
C
但实际上它可以突然取任何值。 -> allowing this would lead to confusion. - >允许这会导致混乱。
What i can offer you is the following code-example, which may be suitable for your case. 我能为您提供的是以下代码示例,它可能适合您的情况。 Although it definitely will be inconvenient to use it.
虽然使用它肯定会不方便。 But as you forward all methods to the OursourcableDeveloperRentable it is possible.
但是当您将所有方法转发到OursourcableDeveloperRentable时,它是可能的。 The comments should explain how it works.
评论应该解释它是如何工作的。
//This class itself can be added to any Developer-lists
public class OutsourcableDeveloper<C> extends Developer<C> {
public final OutSourcableDeveloperRentable RENTABLE_INSTANCE = new OutSourcableDeveloperRentable();
@Override
public Rate<C> getRate(final Taxes<C> taxes) {
// Simply forward to the more general getRate instance.
return this.RENTABLE_INSTANCE.getRate(taxes);
}
public void exampleBehaviourA() {
//Example for how you can make both objects behave equally.
}
// This class can be added to the lists requiring a Rentable
// And the original value can be retrieved by both classes.
public class OutSourcableDeveloperRentable implements Rentable {
public final OutsourcableDeveloper<C> PARENT_INSTANCE = OutsourcableDeveloper.this;
//This method is the one to implement because it is more general than
//the version of OutsourcableDeveloper.
@Override
public <T> Rate<T> getRate(final Taxes<T> taxes) {
// Do your work.
return null;
}
public void exampleBehaviourA() {
//Just an example - Maybe for you it makes for sence to
//forward the method of Oursoursable-Developer to here.
//Then all Behaviour would be found in this class.
OutsourcableDeveloper.this.exampleBehaviourA();
}
}
}
Ok, I found a way to solve it. 好的,我找到了解决问题的方法。 It's clumpsy, but it's the easier one if the architecture is not very complex, inspired by my Why can't I extend an interface "generic method" and narrow its type to my inherited interface "class generic"?
它是块状的,但如果架构不是很复杂,那么它就更容易了,受到我的启发为什么我不能扩展接口“泛型方法”并将其类型缩小到我继承的接口“class generic”? own answer:
自己的答案:
public class OutsourcableDeveloper<C>
extends Developer<C>
implements Rentable{
/* This might not be needed if we don't need to extract C from taxes parameter */
final Class<C> currencyClass;
public OutsourcableDeveloper(Class<C> currencyClass){ this.currencyClass = currencyClass;}
@Override
public Rate<C> getRate(@SuppressWarnings("rawtypes") Taxes taxes){
try{
C taxesCurrency = (C) currencyClass.cast(taxes.getCurrency()); //IF actually needed getting the typed instance
return new Rate<C>(taxesCurrency); //Or whatever processing
} catch (ClassCastException e){
throw new UnsupportedOperationException("OutsourcableDeveloper does not accept taxes in a currency that its not hims");
}
}
}
It is also possible to play with "extends Developer" without the generic type, so it is implictly raw. 也可以使用“extends Developer”而不使用泛型类型,因此它显然是原始的。 but we loose typing for the non-conflicting methods as well
但我们也为非冲突方法打字
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.