我是泛型新手,在尝试在小型程序中使用它们时会遇到以下问题,我将尝试提供必要的信息。
我将尝试只提供必要的内容,但是如果有任何遗漏,请告诉我,我会提供所需的内容。
首先是以下接口:
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
的任何子类,即可以是BnPrice
或MyPrice
。如果T
是BnPrice
,那么它将编译:test.subtractPrice(new BnSPrice(5));
您正在将
BnPrice
传递到需要BnPrice
的方法中。都好。但是,T
不一定必须是BnPrice
。也可以是MyPrice
!如果是MyPrice
怎么办?然后,由于您无法将BnPrice
传递给MyPrice
参数,因此以上行将无法编译。由于参数可以是扩展
BnPrice
的任何类型,因此您不能将BnPrice
传递给它。