java泛型类继承_java泛型类的继承规则

首先看一看java泛型类的使用:

/*** 一个泛型方法:使程序更加安全

* 并且能被更多的使用

*@author丁**

*

*@param*/

class Pair{privateT first;privateT second;//实例化类型变量

public static Pair makePair(Classcl){try{return new Pair<>(cl.newInstance(), cl.newInstance());

}catch(Exception e) {return null;

}

}public Pair(){ first = null; second = null; }public Pair(T first, T second){ this.first = first; this.second =second;}publicT getFirst() {returnfirst;

}public voidsetFirst(T first) {this.first =first;

}publicT getSecond() {returnsecond;

}public voidsetSecond(T second) {this.second =second;

}

}

classFather {private int age = 40;public voidgetName(){

System.out.println(age);

}

}class Son extendsFather{private int age = 12;public voidgetName() {

System.out.println(age);

}

}

在普通类中:Father aa = new Son();父类是可以用来指向子类的

但是在泛型类中却不是如此:

Pair bb = new Pair<>();

Pair cc = bb;//error

1:虽然Son是Father的子类,但是Pair之间没有继承关系:

List a1 = new ArrayList<>();

List a2 = new ArrayList<>();//设a1可以等于a2//a1 = a2;//a1.add(1111);因为是对a1进行操作,所以可以添加Object,a1.add(Object ad);//a2.get(0);报错,因为a1添加Object进入了a2的空间中,但是a2是String类型,所以报错

2:可以将参数化类型转换成一个原始类型:

List a2 = new ArrayList<>();

List a3= a2;//可以通过编译,但是后面使用方法时可能会产生类型错误!//这时候a3对象时原始类型,所以add(Object obj);

a3.add(123);//是对a3进行操作,但是最终结果保存到了a2中,将一个Integer装入String中

显然是错误的;

3:泛型类可以扩展或实现其他的泛型类:

//泛型接口

interface List1{

}//实现了泛型接口的泛型类

class List2 implements List1{

}//泛型类

class List3{

}//继承了其他泛型类的泛型类

class List4 extends List3{

}

List1 b1 = new List2();//因为List2实现了List1

List3 b2 = new List4();//List4继承了List3,所以List3是父类,可以指向子类对象。

虽然这样也完成了泛型类的继承,实现了和普通类一样的多态,但是使用起来并不是特别好,就这样java引入了通配符概念:

通配符上限:

/*通配符的上限:Pair extends Father> c2

extends是关键字

Pair代表的是某个唯一(具体的泛型类)的泛型类:比如Pair,Pair

但是Pair extends Father>不是具体的泛型类,它所指的是参数类型为Father的子类的所有泛型类(包括Father)*/Pair extends Father>c3;

Pair c1 = new Pair<>();

Pair c2 = new Pair<>();//c2 = c1;error

c3 =c1;

c3= c2;

需要注意的是:

/** 使用通配符的上限的问题:

* ? extends Father getFirst();

* void setFirst(? extends Father);

* 当c2= c1时:

* c2.setFirst(Father father);时,会将Father对象添加到Son对象内存中,这是不好的

* 所以使用extends上限时,不能使用setFirst(? extends Father),add(? extends Father)* 等方法。

* 但可以使用getFirst();方法*/

c2.setFirst( new Father(); );//error

通配符下限:

/** 通配符的下限:

* ? super Son

* 表示的不是某个具体的泛型类,而是表示参数类型为Son的父类的所有可能的泛型类(包括* * Son)

* 和通配符上限一样,通配符的超类型限定不能使用getFirst()方法,但可以使用setFirst(XX)方法*/Pair c1 = new Pair<>();

Pair super Son>c3;

c3= c1;

//另一种超类型限定的写法

Pair> c4;

无限定通配符:

//无限定通配符

Pair c7 = new Pair<>();

Pair c5 = new Pair<>();//c7 = c5;error,因为他们不是同一种类型

Pair> c6 = new Pair<>();

c6= c5;//Pair>是所有的Pair泛型类的父类,Pair> c6 = new Pair();

Pair>和Pair的本质不同在于:可以用任意的Object对象调用原始的Pair类的setObject()方法;

通配符的捕获:

//交换First,Second变量值

public static void swap(Pair>p){? t = p.getFirst();//error,因为通配符(?)不是类型变量,所以不能直接将?写入代码中,利用通配符的捕获来解决这个问题。

p.setFirst(p.getSecond());

p.setSecond(t);

}

//交换First,Second变量值

public static void swap(Pair>p){

swapHelper(p);//在调用下面的方法时,类型参数就被捕获了。

}//利用通配符的捕获来解决该问题

public static void swapHelper(Pairp){

T t= p.getFirst();//T是具体的某个类型。

p.setFirst(p.getSecond());

p.setSecond(t);

}

注意:通配符的捕获只有在许多限制的情况下才是合法的,编译器必须能够确信通配符表达的是单个,确定的类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值