我是泛型新手,在尝试在小型程序中使用它们时会遇到以下问题,我将尝试提供必要的信息。

我将尝试只提供必要的内容,但是如果有任何遗漏,请告诉我,我会提供所需的内容。

首先是以下接口:

1: public interface IPrice<T extends IPrice<T>> {
2:     void setPriceToZero();
3:     T addPrice(T price);
4:     T subtractPrice(T price);
5:     T multiplyPriceByFactor(int factor);
6:     String priceToString();
7: }

它由BnSPrice类实现;这可能是其中必要的部分:
1: public class BnSPrice implements IPrice<BnSPrice> {
2:     public BnSPrice subtractPrice(BnSPrice price) {...}
2: }

现在,该部分将无法编译并且我不太了解:
1: public static void main(String[] args){
2:     [...]
3:     IPrice<? extends BnSPrice> test = new BnSPrice(5);
4:     test.subtractPrice(new BnSPrice(5));
5:     [...]
6: }

我得到的是

“错误:(27、28)java:不兼容的类型:main.bnsCalculatorModel.BnSPrice>无法转换为捕获的#1扩展> main.bnsCalculatorModel.BnSPrice”

在我称之为减法的那一行中。

为什么会发生这种情况,我该如何纠正它以便仍然可以对接口进行编程?

(我的目标是将来可以很容易地将我的程序扩展到其他“价格类型”。)

最佳答案

首先,让我们看看如何使这项工作:

IPrice<BnSPrice> test = new BnSPrice(5);
test.subtractPrice(new BnSPrice(5));

好的,因此删除通配符? extends ...是可行的。为什么?

您需要了解通用通配符的概念。 <? extends BnPrice>意味着它可以是BnPrice的子类的任何类型。目前,您还没有任何东西,但是让我们创建一个以证明我的观点。
class MyPrice extends BnPrice {}

请注意,您不能将BnPrice对象分配给MyPrice类型的变量。

大!现在我们有了test对象。让我们看看如何在subtractPrice类型中定义IPrice<? extends BnPrice>:
T subtractPrice(T price);

由于您编写了<? extends BnPrice>,因此T可以是BnPrice的任何子类,即可以是BnPriceMyPrice。如果TBnPrice,那么它将编译:
test.subtractPrice(new BnSPrice(5));

您正在将BnPrice传递到需要BnPrice的方法中。都好。但是,T不一定必须是BnPrice。也可以是MyPrice!如果是MyPrice怎么办?然后,由于您无法将BnPrice传递给MyPrice参数,因此以上行将无法编译。

由于参数可以是扩展BnPrice的任何类型,因此您不能将BnPrice传递给它。

07-24 09:49