如何在不进行转换的情况下覆盖时指定方法参数?

时间:2017-02-21 18:51:07

标签: java generics inheritance interface

我有一个关于方法覆盖的问题,这可能会受到其他一些方面的影响,因此我希望这个问题具有足够的具体性。 上下文:我尝试为某些对象的价格构建一个简单的计算器,但“价格类型”应与逻辑的其余部分解耦,以便客户端只需知道以下接口。

我认为最好用我的问题开始的基本代码进行解释。

public interface InterfacePrice {
    public InterfacePrice addPrices(InterfacePrice price1, InterfacePrice price2);
    public InterfacePrice subtractPrices(InterfacePrice price1, InterfacePrice price2);
    public String priceToString();
}

所以这就是我能用两种价格做的事情。 现在我尝试更多地指定这个:

public class BnSPrice implements InterfacePrice {
    int gold = 0;
    int silver = 0;
    int copper = 0;
    //the following will obviously not compile but i hope it helps explain
    @Override
    public InterfacePrice addPrices(BnSPrice price1, BnSPrice price2) {
    return null;
    [...more code here...]
}

所以我想做的是写一个简单的添加方法,基于事实100铜是一银等等。现在我的问题: 编译器不允许我更改参数以键入BnSPrice,我理解,我只是想说明问题。如果我不知道它们具有正确的类型,那么尝试添加两个具体价格的金币和银币是没有意义的,所以我想到的第一件事就是用正常的InterfacePrice覆盖该方法。参数并在方法开始时进行类型检查并转换为propper类型,但这似乎不是非常有效或美观。

问题:我如何更改设计以获得以后添加其他价格模型的灵活性,而我的客户端代码只需要知道界面? (我只是学习java,如果问题有一些我没看到的明显答案,请原谅我。)可以通过使用泛型来解决吗? (我不太了解那些......我很想把仿制药用于我的脑海里。)

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

由于你想在派生类中应用,对父方法的参数有一些限制,泛型可以帮到你。

使用Generics,您还可以选择在方法中返回参数化类型或InterfacePrice

在具体的类示例中,您可以写:

@Override
public InterfacePrice addPrices(BnSPrice price1, BnSPrice price2) {

我将按照这种方式为addPrices()方法和subtractPrices()方法提供一个示例,我将使用我们想要返回特定类型的方式。

您可以创建一个通用界面:

public interface InterfacePrice<T extends InterfacePrice<T>> {
    public InterfacePrice<T> addPrices(T price1, T price2);
    public T subtractPrices(T price1, T price2);
    public String priceToString();
}

以下是它的实现:

public class BnSPrice implements InterfacePrice<BnSPrice> {
    int gold = 0;
    int silver = 0;
    int copper = 0;

    @Override
    public InterfacePrice<?> addPrices(BnSPrice price1, BnSPrice price2) {
        return ...;
    }

    @Override
    public BnSPrice subtractPrices(BnSPrice price1, BnSPrice price2) {
        return ...;
    }

    @Override
    public String priceToString() {
        return ...;
    }
}