泛型在继承方面的体现 [Java]

泛型在继承方面的体现

情况一:

类A是类B的父类, G< A>和G< B>二者不是子父类关系
  • G< A> 和G< B>是并列关系

我们知道如果两个类之间有继承关系,这个时候这两个类创建的对象,这个时候子类创建的对象就可以赋值给父类的引用 — 也就是形成多态

  • 那么这个时候我们说G< A> 和G< B>之间没有继承关系,这个时候也就是两个类类型相同但是泛型不同的两个模板类是不同的,这个时候我们的不同的泛型就将我们的同一个类区别成了两个不同的类,这两个类可以看成是并列关系,这个时候这两个类类型相同的但是泛型不同的两个对象由于其模板类是并列关系,没有继承关系,这个时候我们就不可以将一个对象赋值给另一个类类型的引用
举例:

eg:

ArrayList<Object> list1 = null;  //创建一个ArrayList<Object> 类型的引用,不指向任何一个实例对象
ArrayList<String> list2 = new ArrayList<>(); //创建一个ArrayList<String> 类型的引用指向一个对                                              //象

list1 = list2;//这个时候编译出错,因为泛型不同的引用之间不可以相互赋值 
情况一的总结:

泛型不同,且这两个泛型之间有继承关系的同一个类创建出来的两个对象之间没有继承关系,是并列的----也就是: 泛型不同的引用之间不可以相互赋值

  • 因为两个泛型不同的引用,这个时候这两个引用指向的对象肯定没有继承关系,这个时候也就不能相互赋值

为什么泛型不同的引用之间不可以相互赋值?

这里我们通过一个例子来解释(我们使用反证法来证明):

如果我们的ArrayList< Object> 和ArrayList< String>有继承关系,这个时候我们的ArrayList< Object> 类型的引用就可以指向ArrayList< String>类型的对象,这个时候在内存层面,其实就是ArrayList< Object>类型的引用指了一个ArrayList< String> 类型的内存空间,这个时候如果我们调用这个ArrayList< Object> 类型的引用,这个时候因为编译期间看的是左边,也就是看的是ArrayList< Object>类型,这个时候我们如果调用add()方法,这个方法中我们要输入的参数就是Object类型的参数,这个时候我们就可以将Integer类型的数据填到这个引用指向的对象中去,而且由于我们的泛型其实就是提供了一个变异期间的检查,这个时候我们的编译期间填入的数据从有限制的String类型的数据变成没有限制的Object类型,这个时候如果我们填入Integer类型的数据,这个时候编译和运行都是可以正常执行的, — > 这个时候我们的这个引用指向的对象的内存空间中就存入了Integer类型的数据,这个时候我们的这个ArrayList< Object>类型的引用指向到其实就是一个ArrayList< String>类型的对象,这个时候就相当于我们给ArrayList< String> 类型对象中添加了Integer类型的数据 ---- 这个时候那么就会有安全隐患,这个时候我们的ArrayList< String >类型的对象中存储了Integer类型的数据 ---- 这合理吗? 这不合理,所以我们的java官方就不允许这种情况的发生,也就是不允许泛型不同的引用之间相互赋值

情况二:

类A继承与类B (也就是类B是类A的父类), A< G> 和 B< G>具有继承关系

这个时候我们就可以声明 B< G>类型的引用指向 A< G>类型的对象 — > 这个时候就是形成了多态

举例:
List<String> list1 = null;   //声明了一个List<String> 类型的引用,没有指向一个实例对象
ArrayList<String> list2 = new ArrayList<>(); //声明了一个ArrayList<String> 类型的引用,指向了一                                              //个实例对象

list1 = list2; //这个时候编译是通过的,因为我们的这个两个泛型相同的继承类之间还是有继承关系的,这个时候也就可以使用父类的引用指向子类的对象

情况三:

同一个泛型类A,如果这个时候一个没有声明泛型,一个声明了泛型G,这个时候我们的没有泛型的这个类和指明了泛型为G的这个类创建的两个引用, 这两个引用之间可以相互赋值

A 类型的引用和 A< G>类型的引用之间可以相互进行赋值:

  • 这个特殊情况其实也就是我们的不指明泛型和指明泛型为Object类型的区别
    • 如果指明泛型为Object类型之后这个类创建出来的引用不可以和其他泛型类创建出来的引用进行相互赋值
    • 如果没有指明泛型,这个时候这个没有指明泛型的引用和指明了这个类指明了泛型声明的引用之间可以相互进行赋值

举例:

ArrayList list1 = new ArrayList;  
ArrayList<String> list2 = new ArrayList<>();
 
list1 = list2; //这个时候编译不会出错, 没有声明泛型的引用可以和这个声明了泛型的引用进行相互赋值
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值