Java 如何在不强制转换的情况下重写时指定方法参数?

Java 如何在不强制转换的情况下重写时指定方法参数?,java,generics,inheritance,interface,Java,Generics,Inheritance,Interface,我有一个关于方法重写的问题,它可能受到其他方面的影响,所以我希望这个问题足够具体。 上下文:我试图为某些对象的价格构造一个简单的计算器,但“价格类型”应与逻辑的其余部分分离,以便客户只需要知道以下接口 我认为最好用我的问题开始的基本代码来解释 public interface InterfacePrice { public InterfacePrice addPrices(InterfacePrice price1, InterfacePrice price2); public

我有一个关于方法重写的问题,它可能受到其他方面的影响,所以我希望这个问题足够具体。 上下文:我试图为某些对象的价格构造一个简单的计算器,但“价格类型”应与逻辑的其余部分分离,以便客户只需要知道以下接口

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

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铜等于1银的事实,依此类推。现在我的问题是: 编译器不允许我将参数更改为BnSPrice类型,我理解,我只是想说明这个问题。如果我不知道它们有正确的类型,那么尝试添加两种具体价格的金币和银币是没有意义的,因此我想到的第一件事是获得正确的行为是使用正常的InterfacePrice参数覆盖该方法,并在方法开始时进行类型检查,然后将其转换为propper类型,但是这似乎不是很有效率,也不是很漂亮

问题:当我的客户机代码只需要知道接口时,如何更改设计以获得以后添加其他价格模型的灵活性? (我只是在学习java,所以如果这个问题有一些我看不到的明显答案,请原谅我。)它可以通过使用泛型来解决吗?(我对这些不太了解……我正在努力让自己记住泛型的用法。)


提前感谢您的帮助。

由于您希望在派生类中应用,父方法、泛型参数的一些约束可以帮助您。

对于泛型,您还可以选择在方法中返回参数化类型或
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();
}
公共接口价格{
公共接口价格附加价格(T价格1,T价格2);
公共T价(T价1,T价2);
公共字符串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 ...;
    }
}
public类BnSPrice实现InterfacePrice{
int gold=0;
int银=0;
int铜=0;
@凌驾
公共接口价格附加价格(B价格1、B价格2){
返回。。。;
}
@凌驾
公共服务价格(服务价格1、服务价格2){
返回。。。;
}
@凌驾
公共字符串priceToString(){
返回。。。;
}
}

您的问题是,如何只允许使用兼容的price对象(例如gold和silver)调用addPrice,而不允许使用不兼容的类型?或者你怎么能添加两个使用同一界面的不同对象呢?首先,davidxxx的答案是对我遇到的问题的明确回答。啊,这是有道理的!谢谢你简洁的回答;这真的帮了我的忙!现在我有一个小的后续问题:我描述的问题的结构是泛型的主要目的吗?欢迎你:)显然,如果你通过接口编程并在处理代码时操作接口,你不需要在实际代码中执行instanceof和cast。泛型的使用在某种程度上弥补了Java中方法重写/实现的不足,因为重载/实现方法的参数类型必须与原始定义中定义的参数类型相同。在某些情况下,这是可取的,因为您认为对param类型应用此约束很重要。在其他情况下,这是一种开销,它违反了liskov原则,没有什么好的理由。嗯,好吧……我在谷歌上搜索了liskov原则。你对我问题的解决方案没有违反这一点,还是我错了?嗯,对利斯科夫来说,你可能是对的。事实上,我想说的是,你们不能再通过接口编程了。此代码未编译:
InterfacePrice>price=new BnSPrice();price.addPrices(new BnSPrice(),new BnSPrice())在不使用泛型的情况下,此代码编译:
InterfacePrice=new BnSPrice();price.addPrices(new BnSPrice(),new BnSPrice())addPrice,只有一个参数).但是,当addPrice方法适用于所有InterfacePrice时,为什么会出现这种情况呢。根据你最后的评论,我可能没有正确理解,如果我失去了编程到接口而不是特定实现的能力,我不确定使用泛型会赢得什么。