黑马程序员技术交流社区

标题: Comparator<? super T> 为什么是super而不是extends? [打印本页]

作者: noiary    时间: 2014-10-8 16:14
标题: Comparator<? super T> 为什么是super而不是extends?
List<? extends T> list
我理解是定义集合后可以把T的子类装入集合,
因为调用list.xx()方法时相当于都是父类方法,子类也会具备.

那么Comparator怎么理解呢?
Comparator<? super T> 为什么是super而不是extends?

作者: liaorubei    时间: 2014-10-8 17:27
这个泛型限定<? super T> 意思是可以用T的自己本身,也可以用T的父类,比如你有两个子类都是继承自一个父类,如果你想对这两个子类的集合时行排序时,如果没有泛型限定,那么你就要写两个子类的比较器实现,如果使用了super关键字,说明这个子类元素排序时可以接收它们父类的比较器,这样一样,就只要写父类的比较器实现就可以了.
作者: noiary    时间: 2014-10-8 18:04
liaorubei 发表于 2014-10-8 17:27
这个泛型限定

谢谢解惑,

不过为什么可以接收父类呢? 为什么不能接受子类?
作者: 水竹    时间: 2014-10-8 18:25
noiary 发表于 2014-10-8 18:04
谢谢解惑,

不过为什么可以接收父类呢? 为什么不能接受子类?

你定义了一个集合,集合里面存了一堆T类型的元素,要想对这些元素进行比较的话,该怎么比呢?
首先,你必须比较这些元素都有的东西对吧。
比如说T是人类,我定义了一个集合用来存放人类,我传了一个学生类实例和一个工人类实例,学生有学号,工人有工号,这是两个子类特有的内容,显然在存放人类的集合里面是不能比较的,不然学生拿学号和工人比较大小这不是很荒谬么?人家都没有咋比。
上面这一点,就决定了比较器不能是T的子类的,在刚才的例子中,也就是说不能用比较学生的比较器去比较人类。
下面说super。
既然要比较共性的话,那么什么是共性呢?
显然既然存放的都是T或者T的子类,那么T类中包含的属性就是所有元素的共性,所以传入比较器的时候传集合刚才定义的那个类型就好了。
然而是不是只有这一种情况呢?显然不是。
还是刚才那个例子,有个存人类的集合,集合中可以存入人类或者它的子类:学生和工人类,而这个人类呢,实际上它有个父类,叫做生物类,人类继承自生物类,所以生物类中定义的属性、方法都是人类的共性,学生、工人显然也具备它们的间接父类生物类的共性。比如说年龄,生物可以都有年龄吧(微生物或许不叫年龄,它们生命太短,但是肯定也有表示活了多久的属性吧!),人类作为它的子类不是也有年龄么,学生和工人不是也有年龄么,所以定义一个比较器比较的类型是生物,比较的内容就是按照生物的年龄,那么这个比较器显然也是能够比较人类的。
所以,给集合传入比较器的时候,只要传一个集合泛型中定义类型(人类)的父类(生物),即<? super T>同样正确。
作者: noiary    时间: 2014-10-8 21:26
水竹 发表于 2014-10-8 18:25
你定义了一个集合,集合里面存了一堆T类型的元素,要想对这些元素进行比较的话,该怎么比呢?
首先,你必 ...

赞,基本上懂了.不过Comparator接口这里的基础知识貌似我很迷糊,回头得仔细复习一下.


感谢,写得非常生动形象!
作者: 水竹    时间: 2014-10-8 21:29
noiary 发表于 2014-10-8 21:26
赞,基本上懂了.不过Comparator接口这里的基础知识貌似我很迷糊,回头得仔细复习一下.

嗯,懂了就好。我当初看视频的时候泛型上限这里也没听明白,后来自己查API文档,找了几个带着泛型上限的例子看了一下,才完全明白过来的。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2