黑马程序员技术交流社区

标题: 说到泛型,我请教一下---泛型限定中,使用<? super XXX><已解决> [打印本页]

作者: 李天甲    时间: 2012-6-7 13:59
标题: 说到泛型,我请教一下---泛型限定中,使用<? super XXX><已解决>
本帖最后由 李天甲 于 2012-6-13 07:27 编辑

毕老师第十五天,第12段视频中的练习6时候,讲到泛型的限定问题...

通配符可以限定子类用extends ,也可以限定父类用super 谁能给一个用super的例子啊......

然后我把老师例子中的代码改了一下参见
  1. import java.util.*;
  2. /*
  3. ? 通配符。也可以理解为占位符。
  4. 泛型的限定;
  5. ? extends E: 可以接收E类型或者E的子类型。上限。
  6. ? super E: 可以接收E类型或者E的父类型。下限

  7. */
  8. class GenericDemo6 {
  9. public static void main(String[] args) {
  10. ArrayList<PersonG1> al = new ArrayList<PersonG1>();
  11. al.add(new PersonG1("abc1"));
  12. al.add(new PersonG1("abc2"));
  13. al.add(new PersonG1("abc3"));
  14. //printColl(al);
  15. ArrayList<StudentG1> al1 = new ArrayList<StudentG1>();
  16. al1.add(new StudentG1("abc--1"));
  17. al1.add(new StudentG1("abc--2"));
  18. al1.add(new StudentG1("abc--3"));
  19. printColl(al);
  20. printColl(al1);
  21. }
  22. public static void printColl(Collection<? super StudentG1> al) { //更改后的,限定传入Student1的父类

  23. Iterator<? super StudentG1> it = al.iterator(); //传入Student1的父类.....
  24. while (it.hasNext()) {
  25. System.out.println(it.next().getName()); //然后就报错了,说是找不到方法getName();
  26. }
  27. }
  28. }
  29. class PersonG1 {
  30. private String name;

  31. PersonG1(String name) {
  32. this.name = name;
  33. }

  34. public String getName() {
  35. return name;
  36. }
  37. }
  38. class StudentG1 extends PersonG1 {
  39. StudentG1(String name) {
  40. super(name);
  41. }
  42. }
  43. class CompG1 implements Comparator<PersonG1> {
  44. public int compare(PersonG1 s1, PersonG1 s2) {
  45. return s1.getName().compareTo(s2.getName());
  46. }
  47. }


复制代码
运行结果出错,说是找不着getName方法???是为何呢?
求教.......



作者: 王渠    时间: 2012-6-7 14:26
本帖最后由 王渠 于 2012-6-7 14:29 编辑
  1. public static void printColl(Collection<? super StudentG1> al) { //更改后的,限定传入Student1的父类

  2. Iterator<? super StudentG1> it = al.iterator(); //传入Student1的父类.....
  3. while (it.hasNext()) {
  4. System.out.println(it.next().getName()); //然后就报错了,说是找不到方法getName();
  5. }
复制代码
这个是你代码的方法,
这里应该清楚你传进al的究竟是什么,
Collection 表示一组对象
getName方法只有PersonG1才有,所以需要强转类型
所以代码应该修改下
  1. public static void printColl(Collection<? super StudentG1> al) { //更改后的,限定传入Student1的父类

  2. Iterator<? super StudentG1> it = al.iterator(); //传入Student1的父类.....
  3. while (it.hasNext()) {
  4. System.out.println(((PersonG1)it.next()).getName()); //只有PersonG1对象才可以调用getName方法
  5. }
  6. }
复制代码

作者: 李天甲    时间: 2012-6-7 14:35
王渠 发表于 2012-6-7 14:26
这个是你代码的方法,
这里应该清楚你传进al的究竟是什么,
Collection 表示一组对象

那么调用<? super StudentG1>所表示的类是Student的父类PersonG1呢,还是直接变成了OBJECT类了呢.
怎么试验都像是限定成了Object......只有object默认的一些方法可以用....
作者: 王渠    时间: 2012-6-7 14:37
补充一下,因为你有将两组对象都导入到Collection,这样就出现了一个问题,就是StudentG1对象是不能被强转成父类对象的,所以,也就只能都转成了PersonG1
作者: 李天甲    时间: 2012-6-7 14:51
额...看来这个问题给的例子失败了....谁能给个用super限定泛型的例子啊.....
作者: 王渠    时间: 2012-6-7 14:53
李天甲 发表于 2012-6-7 14:35
那么调用

局限性是因为你定义的类中的方法本身有限,可以在父类中定义自己想要的相应方法,可以使用contions中的方法来操作contion集合
作者: 王渠    时间: 2012-6-7 15:08
本帖最后由 王渠 于 2012-6-7 16:02 编辑
李天甲 发表于 2012-6-7 14:51
额...看来这个问题给的例子失败了....谁能给个用super限定泛型的例子啊.....

比如说一个类是Animal,它的子类是狗,Dog下面有子类是PetDog,这样你如果用的是
  1. (collection<? super PetDog> x)
复制代码
你就可以向里面传入Dog,或者Animal对象元素了
作者: 李天甲    时间: 2012-6-7 15:11
本帖最后由 李天甲 于 2012-6-7 15:39 编辑

编辑掉刚才写的...理解的一塌糊涂......

作者: 李天甲    时间: 2012-6-7 15:38
王渠 发表于 2012-6-7 15:08
比如说一个类是Animal,它的子类是狗,Dog下面有子类是PetDog,这样你如果用的是 ...

看了您给的例子,得,又晕了   晕了   {:soso_e136:}{:soso_e135:}
(collection<? super PetDog>) x)
这是给collection传递泛型的参数么?
定义泛型类
class Utils<QQ>
{
     private QQ q;
     public void setObject(QQ q)
     {
         this.q = q;
     }
    public QQ getObject()
     {
     return q;
     }
}
然后我new这个Utils的时候可以给这个QQ赋值,我可以这样理解么?
Utils<persion> u = new Utils<persion>();
这个时候的<persion>类就传给了QQ,utils里面的private QQ q;就等于 private persion q;
但是如果我这样写
Utils<? super persion> u = new Utils<? super Persion>();   这是啥意思呢?能这样写么?

到底<? extends XXX> 是用作定义啊,还是传参啊.....
作者: 王渠    时间: 2012-6-7 15:58
李天甲 发表于 2012-6-7 15:38
看了您给的例子,得,又晕了   晕了   
(collection

用作定义可传参数的范围啊,<? extends XXX> 就是说可以传xxx类及其子类对象元素
比如Person对象下面有Work,Student子类,那定一个比较器,用的限定是<? extends Person>
这样,无论是Work还是Student都可以用这个比较器了
作者: 孙峰    时间: 2012-6-8 01:15
王渠 发表于 2012-6-7 14:26
这个是你代码的方法,
这里应该清楚你传进al的究竟是什么,
Collection 表示一组对象

StudentG不是继承了PersonG1吗?里面也应该有getName方法啊。




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