Java泛型——泛型作为方法参数和方法重载
泛型作为方法参数
案例需求
(1) 定义一个抽象类Goods,包含抽象方法sell()
(2) 分别定义类Book、Clothes和Shoes继承Goods,并实现sell()方法,输出一句话,如:sell books
(3) 定义一个商品销售类GoodsSeller,模拟销售,包括方法:
public void sellGoods(List goods),循环调用List对象的sell()方法
(4) 测试
前置条件
定义抽象类Goods和抽象方法sell()
package com.study.generic;
public abstract class Goods {
public abstract void sell();
}
### 定义子类:Book、Clothes和Shoes
```java
package com.study.generic;
public class Book extends Goods {
@Override
public void sell() {
System.out.println("sell books");
}
}
public class Clothes extends Goods {
@Override
public void sell() {
System.out.println("sell clothes");
}
}
public class Shoes extends Goods {
@Override
public void sell() {
System.out.println("sell shoes ");
}
}
定义一个商品销售类GoodsSeller,模拟销售
package com.study.generic;
import java.util.List;
public class GoodsSeller {
public void sellGoods(List<? extends Goods> goods){
//调用集合中的sell方法
for(Goods g:goods){
g.sell();
}
}
}
注:<? extends Goods>
表示只要添加的对象泛型是Goods类以及Goods的子类,都是允许的。
测试
package com.study.generic;
import java.util.ArrayList;
import java.util.List;
public class GoodsTest {
public static void main(String[] args) {
//定义book相关的List
List<Book> books=new ArrayList<Book>();
books.add(new Book());
books.add(new Book());
//定义clothes相关的List
List<Clothes> clothes=new ArrayList<Clothes>();
clothes.add(new Clothes());
clothes.add(new Clothes());
//定义shoes相关的List
List<Shoes> shoes=new ArrayList<>();
shoes.add(new Shoes());
shoes.add(new Shoes());
GoodsSeller goodsSeller=new GoodsSeller();
goodsSeller.sellGoods(books);
goodsSeller.sellGoods(clothes);
goodsSeller.sellGoods(shoes);
}
}
运行结果:
sell books
sell books
sell clothes
sell clothes
sell shoes
sell shoes
泛型作为方法重载
前面我们学习了泛型作为方法参数,那么下面通过例题看一下泛型作为方法参数和方法重载的关联。
从下面的案例中可以看到,参数类型可以是Number的子类,所以方法调用时,参数是整型的123和浮点型的5.0f都是正确的,都可以输出结果。
运行结果:
123
5.0
如下图所示,在GenericMethod类中添加一个printValue()方法,参数类型是Integer,也就是Number的一个子类,会发现程序并没有报错,而是和上面的printValue(T t)方法形成了方法的重载。新增加方法的输出语句,增加了Integer的输出,为了和上面的方法输出进行区分。
运行结果:
Integer:123
5.0
从运行结果可以看出,这里会优先调用Integer作为参数的printValue()方法,而不是泛型作为参数的方法。
下面再来看一种形式,增加了Number作为参数的方法,可以发现程序报错了。错误提示是:Erasure of method printValue(Number) is the same as another method in type GenericMethod
,也就是这个方法和GenericMethod中的另一个方法一样,也就是和第一个T作为参数的方法一样。说明它们虽然表面看来不一样,但编译后的形式是一样的,因此这样写是不合法的。