我是仿制药的新手,当我试图在一个小程序中使用它们时遇到了以下问题,我将尝试提供必要的信息。
我会尝试只提供必要但如果遗漏任何内容,请告诉我,我会提供所需的信息。
首先是以下界面:
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&gt;无法转换为捕获#1的扩展&gt; main.bnsCalculatorModel.BnSPrice”
在我称之为减法方法的行中。
为什么会发生这种情况,如何纠正这个问题,以便我仍然可以编程到界面?
(我的目标是,将来以其他“各种价格”扩展我的计划应该很容易。)
答案 0 :(得分:6)
首先,让我们看看如何使这项工作:
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
的任何子类,即BnPrice
或MyPrice
。如果T
为BnPrice
,则会编译:
test.subtractPrice(new BnSPrice(5));
您正在将BnPrice
传递给期望BnPrice
的方法。都好。 但是,T
不一定必须是BnPrice
。它也可以是MyPrice
!如果是MyPrice
怎么办?然后上面的行无法编译,因为您无法将BnPrice
传递给MyPrice
参数。
由于参数可以是任何扩展BnPrice
的类型,因此您无法将BnPrice
传递给它。
答案 1 :(得分:0)
因为测试类型是IPrice<? extends BnSPrice>
,所以减法参数的预期类型是? extends BnSPrice
,而不是BnSPrice。
这将编译:
BnSPrice test = new BnSPrice(5);
test.subtractPrice(new BnSPrice(5));