方法参数的泛型类型转换不可能,为什么?

Wol*_*one 3 java generics

我是仿制药的新手,当我试图在一个小程序中使用它们时遇到了以下问题,我将尝试提供必要的信息.

我会尝试只给出必要的但如果遗漏任何东西,请告诉我,我会提供所需的东西.

第一件事是以下界面:

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: }
Run Code Online (Sandbox Code Playgroud)

它由BnSPrice类实现; 这里可能是必要的一部分:

1: public class BnSPrice implements IPrice<BnSPrice> {
2:     public BnSPrice subtractPrice(BnSPrice price) {...}
2: }
Run Code Online (Sandbox Code Playgroud)

现在这部分不会编译,我不明白:

1: public static void main(String[] args){
2:     [...]
3:     IPrice<? extends BnSPrice> test = new BnSPrice(5);
4:     test.subtractPrice(new BnSPrice(5));
5:     [...]
6: }
Run Code Online (Sandbox Code Playgroud)

我得到的是

"错误:(27,28)java:不兼容的类型:main.bnsCalculatorModel.BnSPrice>无法转换为捕获#1的?extends> main.bnsCalculatorModel.BnSPrice"

在我称之为减法方法的行中.

为什么会发生这种情况?如何更正此问题以便我仍然可以编程到界面?

(我的目标是将来用其他"种类的价格"扩展我的程序应该很容易.)

Swe*_*per 6

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

IPrice<BnSPrice> test = new BnSPrice(5);
test.subtractPrice(new BnSPrice(5));
Run Code Online (Sandbox Code Playgroud)

好的,所以删除通配符? extends ...有效.为什么?

您需要了解通用通配符的概念.<? extends BnPrice>意味着这可以是任何类型的子类BnPrice.目前,你没有,但让我们创建一个,以证明我的观点.

class MyPrice extends BnPrice {}
Run Code Online (Sandbox Code Playgroud)

请注意,您无法将BnPrice对象分配给类型的变量MyPrice.

大!现在我们有了自己的test对象.让我们看看如何subtractPrice在类型中定义IPrice<? extends BnPrice>:

T subtractPrice(T price);
Run Code Online (Sandbox Code Playgroud)

因为你写的<? extends BnPrice> T可以是任何子类,BnPrice即它可以是BnPriceMyPrice.如果TBnPrice,那么这将编译:

test.subtractPrice(new BnSPrice(5));
Run Code Online (Sandbox Code Playgroud)

你正在传递一个BnPrice期望a的方法BnPrice.都好.但是,T不一定非必须如此BnPrice.它也可以MyPrice!如果它是MyPrice什么?然后上面的行将无法编译,因为您无法将a传递BnPriceMyPrice参数.

由于参数可以是任何扩展的类型BnPrice,因此您无法传递BnPrice给它.