java中extends jframe是什么意思_java泛型中extends和super的区别

基本用法可以参考下面这个问题中胖君的回答

Java 泛型 <? super T> 中 super 怎么 理解?与 extends 有何不同?​www.zhihu.com
b22227b4fcd721775a96211b43bfeaea.png
胖君​www.zhihu.com
7d8780f944b672d1413af487c66a923e.png

有些疑惑的点在这篇文章中再详细解决一下。

  1. <? extends T>:上界通配符

要点1:实例化时的类只能是定义时类本身或其子类,也就是说T是它的上界。

import java.util.*;

class Food{
	String name = "Food";
}
class Fruit extends Food{
	String name = "Fruit";
}
class Apple extends Fruit {
	String name = "Apple";
}

// 定义时指定T为Fruit
List<? extends Fruit> list;

// 实例化时类只能是T本身或它的子类
list= new ArrayList<Fruit>(); //可以
list= new ArrayList<Apple>(); //可以
list= new ArrayList<Food>();  //报错

要点2:上界通配符add失效(只能add null),可以get

list = new ArrayList<Fruit>();
list.add(new Fruit()); //报错
list.add(null);  //可以
list.get(0); //可以

既然不能add,那里面没东西又get什么呢?所以需要在实例化的时候就把东西都放进去:

list = new ArrayList<Fruit>(){{
	    	add(new Fruit()); // Fruit及其子类都可以放进去
	    	add(new Apple()); // Fruit及其子类都可以放进去
	    	}};

要点3:能放进去的对象类型其上界为实例化时指定的T:

List<? extends Fruit> list list= new ArrayList<Apple>(){{
	    	add(new Fruit()); // 实例化时指定的T为Apple,放入Fruit对象会报错
	    	add(new Apple()); // Apple及其子类都可以放进去
	    	}};

所以能放进去的对象不是看定义时T指定的类,而是看实例化时T指定的类。

2. <? superT>:下界通配符

要点1:实例化时的类只能是定义时类本身或其父类,也就是说T是它的下界。

// 定义时指定T为Fruit
List<? super Fruit> list2;

// 实例化时只能是T本身或它的父类
list2 = new ArrayList<Fruit>(); // 可以
list2 = new ArrayList<Food>(); // 可以
list2 = new ArrayList<Apple>();  // 报错

要点2:添加对象时,在实例化时添加和实例化后添加的对象限制不同(特别注意!):

1. 在实例化时添加的对象只有一个限制:上界为实例化时指定的T。来看一个有趣的现象,即使定义时指定的T是Fruit,但实例化时可以用Fruit的邻居类:

class Food{
	String name = "Food";
}
// 新定义一个Meat类,和Fruit都继承Food
class Meat extends Food{
	String name = "Meat";
}
class Fruit extends Food{
	String name = "Fruit";
}
class Apple extends Fruit {
	String name = "Apple";
}

List<? super Fruit> list2 = new ArrayList<Food>(){{
	    	add(new Object()); // 报错,上界为Food
	    	add(new Meat()); // 可以,是Food的子类,即使不是Fruit
	    	add(new Food()); // 可以
	    	add(new Fruit()); // 可以,是Food的子类
	    	add(new Apple()); // 可以,是Food的子类
	    	}};

2. 在实例化后添加的对象,其上界是定义时指定的T:

list2.add(new Meat());   // 报错,不是Fruit或其子类
list2.add(new Food());   // 报错,不是Fruit或其子类
list2.add(new Fruit());  // 可以
list2.add(new Apple());  // 可以

要点3:上界通配符get出来的对象默认是Object类型,可以做强制类型转换,可以add

Object object = list2.get(0);
Meat meat = (Meat)list2.get(0); // 如果不是Object,需要强制类型转换
System.out.println(meat.name); // 输出meat
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值