我正在创建一个覆盖方法签名的类,该方法签名在2个已实现接口之间的擦除是相同的,但在泛型类型方面有微小差异(一个是方法推断的类型,另一个是方法推断的类型)。我正在寻找一个整洁的解决方案。我只能编辑继承的类,而不是原始的旧版接口。

为了说明这种情况,我制作了一个抽象样本,以了解问题所在:

我有一个开发人员遗留的父类:

public class Developer<C>{
    Rate<C> getRate(Taxes<C> tax){ /*...*/ }
}

我还获得了一个Rentable旧版界面,签名几乎相同
public interface Rentable {
    <C> Rate<C> getRate(Taxes<C> taxes);
}

由于开发人员不可租用,因此在我的模型中,我创建了一个特殊的
既是开发商又是可出租材料的开发商。
public class OutsourcableDeveloper<C>
                 extends Developer<C>
                 implements Rentable{
   @Override
   public Rate<C> getRate(Taxes<C> taxes){ /*...*/}
}

然后我就臭名昭著

名称冲突:类型的方法getRate(Developer.Taxes)
OutsourcableDeveloper与
类型为Rentable的getRate(Developer.Taxes),但不会覆盖它

我如何摆脱它,所以OutsourcableDeveloper.getRate()隐藏了
开发人员和租赁人员。 getRate()?

未能通过普通的覆盖操作似乎有点不合逻辑,但是在擦除相等时不允许扩展两个签名。

当我不打算在实现中调用任何超类时,一个超类从de方法推断类型,另一个从类推断类型真的真的有那么重要吗?考虑到这种简化,也许有技巧来克服这个问题吗?

编辑:我对我的实际问题打开了一个更抽象,不太面向解决方案的问题,以讨论继承设计问题,我认为这是我所遇到的实际问题的相关本质:Why can't I extend an interface "generic method" and narrow its type to my inherited interface "class generic"?

编辑2:上一个问题将我引到此处发布的答案

最佳答案

好吧,他们实际上并不平等。因为任何Rentable-Instance都允许给出任何类型参数T,而OutsourcableDeveloper对其进行了限制。

当然,您可以假设您的情况很容易使用

<C> Rate<C> getRate(Taxes<C> taxes);

接口版本。但是,如果开发人员想继承OutsourceableDeveloper,那么请期待开发人员会有多困惑。根据开发人员的定义,他可以假定方法getRate固定为C,但实际上它可以突然取任何值。 ->允许这样做会导致混乱。

我可以为您提供以下代码示例,它可能适合您的情况。尽管使用它肯定会很不方便。但是当您将所有方法转发到OursourcableDeveloperRentable时,这是可能的。评论应说明其工作原理。
//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();
        }

    }
}

09-25 20:34