一 没有泛型的世界
以一个小故事背景 来慢慢阐述泛型引入必要性
春节临近,在上海工作的云南小伙小明要带山东女朋友第一次回老家过年,回家之前他特定嘱咐妈妈多准备些水果,因为女朋友爱吃水果,但没告诉具体的水果。因为云南盛产香蕉,平时家里经常吃香蕉,所以就没准备香蕉,而是准备了当地卖的比较贵的 山东红富士。然而,女朋友小丽因为知道云南盛产香蕉,满怀期待的认为一定会吃到很多香蕉。于是,就闹出了乌龙事件
二 以程序来阐述没有泛型的世界
- 主角登场
//小丽
public class Xiaoli extends Person {
public void eat(Banana banana){
//正准备高兴的吃香蕉的时候,发现是苹果,生气了
System.out.println("小丽吃"+ banana);
}
@Override
public String toString() {
return "Xiaoli";
}
}
//小明
public class XiaoMing extends Person{
//取标准的盘子 让家人放水果
public RawPlate getPlate(){
return new RawPlate();
}
@Override
public String toString() {
return "XiaoMing";
}
}
//小明妈妈
public class XiaoMingMa extends Person {
//拿盘子放水果(默认苹果)
public void addFruit(RawPlate rawPlate){
rawPlate.set(new Apple());
}
@Override
public String toString() {
return "XiaoMingMa";
}
- 招待引起的乌龙
public void scene0(){
Xiaoli xiaoli = new Xiaoli();
XiaoMing xiaoMing = new XiaoMing();
XiaoMingMa xiaoMingMa = new XiaoMingMa();
RawPlate rawPlate = xiaoMing.getPlate();
xiaoMingMa.addFruit(rawPlate);
xiaoli.eat((Banana) rawPlate.get());
}
虽然 能够编译通过,但运行出现错误
Exception in thread "main" java.lang.ClassCastException: fastec.com.rrcc.generics.demo01.Apple cannot be cast to fastec.com.rrcc.generics.demo01.Banana
at fastec.com.rrcc.generics.demo01.Test1.scene0(Test1.java:30)
at fastec.com.rrcc.generics.demo01.Test1.main(Test1.java:19)
小丽只吃香蕉,所以方法只接受Banana,获取到的Apple 不能强转为香蕉
三 泛型引入 问题解决
准备一个智能的盘子 既可以装苹果、也可以装香蕉
- 盘子的改进
public interface Plate<T> {
public void set(T t);
public T get();
}
//标准盘子
public class RawPlate implements Plate{
private List items = new ArrayList(10);
public RawPlate(){
}
@Override
public void set(Object fruit) {
items.add(fruit);
}
@Override
public Object get() {
int index = items.size() -1;
if(index>= 0){
return (Fruit) items.get(index);
}else{
return null;
}
}
@Override
public String toString() {
return "RawPlate{" +
"items=" + items +
'}';
}
}
//智能盘子
public class AIPlate<T> implements Plate<T> {
List<T> items = new ArrayList<T>();
public AIPlate() {
}
public AIPlate(T t) {
items.add(t);
}
@Override
public void set(T t) {
items.add(t);
}
@Override
public T get() {
int index = items.size() -1;
if(index>= 0){
return items.get(index);
}else{
return null;
}
}
@Override
public String toString() {
return "AIPlate{" +
"items=" + items +
'}';
}
}
- 小明 与 妈妈 给盘子 与 装水果的方法 改进
public class XiaoMing extends Person{
public RawPlate getPlate(){
return new RawPlate();
}
//引入 泛型方法
public <T> AIPlate<T> getAIPlate(){
return new AIPlate<T>();
}
@Override
public String toString() {
return "XiaoMing";
}
}
public class XiaoMingMa extends Person {
public void addFruit(RawPlate rawPlate){
rawPlate.set(new Apple());
}
/**
* 这里不是泛型方法,这只是一个普通方法,只是使用了AIPlate<Banana> 这个泛型类做形参而已
* @param aiPlate
*/
public void addFruitToAi(AIPlate<Banana> aiPlate){
aiPlate.set(new Banana());
}
@Override
public String toString() {
return "XiaoMingMa";
}
}
3.问题解决 重新招待
public void scene1(){
Xiaoli xiaoli = new Xiaoli();
XiaoMing xiaoMing = new XiaoMing();
XiaoMingMa xiaoMingMa = new XiaoMingMa();
AIPlate<Banana> aiPlate = xiaoMing.getAIPlate();
xiaoMingMa.addFruitToAi(aiPlate);
xiaoli.eat(aiPlate.get());
}
网友评论