简体   繁体   English

名称冲突,覆盖失败,在实现具有相同擦除的两个接口的类上

[英]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.

相关问题 由于相同的擦除而命名冲突 - Name clash because of same erasure 如何解决名称冲突有相同的擦除? - How to solve name clash have the same erasure? Java泛型名称冲突,具有相同的擦除 - Java generics name clash , has the same erasure 实现Comparable,compareTo名称冲突:“具有相同的擦除,但不会覆盖其他” - Implementing Comparable, compareTo name clash: “have the same erasure, yet neither overrides the other” 界面和一个类。名称冲突:相同的擦除,但都不会覆盖其他 - interface and a class. name clash: same erasure, yet neither overrides other 类型分区器的getPartition的名称冲突在MapReduce,Hadoop中具有与类型主类相同的擦除 - Name clash of getPartition of type Partitioner has the same erasure of type main class in MapReduce, Hadoop 名称冲突:类型为test2的方法add(Object)具有与HashSet类型的add(E)相同的擦除 <E> 但不会覆盖它 - Name clash: The method add(Object) of type test2 has the same erasure as add(E) of type HashSet<E> but does not override it Java名称冲突,具有相同的擦除方式,但两者都不隐藏 - Java name clash, have the same erasure, neither hides the other Java名称冲突错误,一种方法与另一种方法具有相同的擦除 - Java name clash error, a method has the same erasure as another method 两个具有相同方法名称的接口,当我覆盖时会发生什么? - Two interfaces with same method name, what happens when I override?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM