A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 徐帅 中级黑马   /  2012-5-25 13:04  /  2278 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

为什么已经继承了Person. 编译器提示无法通过方法调用转换实际参数TreeSet<Student>.TreeSet<Worker>
转换为TreeSet<Person>,而将<Person> 改为<? extends Person> 却可以呢?
请大侠帮忙解答下

import java.util.*;

class Person
{
        private String name;

        Person(String name)
        {
                this.name = name;
        }
        public String getName()
        {
                return name;
        }
}

class Worker extends Person
{
        Worker(String name)
        {
                super(name);
        }
}

class Student extends Person
{
        Student(String name)
        {
                super(name);
        }
}



class  GeneticDemo4
{
        public static void main(String[] args)
        {
                TreeSet<Student> ts1 = new TreeSet<Student>(new comp());

                ts1.add(new Student("hehe 1"));
                ts1.add(new Student("hehe 3"));
                ts1.add(new Student("hehe 24"));
                ts1.add(new Student("hehe 79"));
                ts1.add(new Student("hehe 40"));

                printCll(ts1);
       
                TreeSet<Worker> ts2 =new TreeSet<Worker>(new comp());

                ts2.add(new Worker("he 1"));
                ts2.add(new Worker("he 3"));
                ts2.add(new Worker("he 9"));
                ts2.add(new Worker("he 2"));
                ts2.add(new Worker("he 5"));
               
                printCll(ts2);       
        }

                public static void printCll(TreeSet<Person> al)
           {
                        Iterator<Person>  it = al.iterator();
                        while (it.hasNext())
                        {
                                System.out.println(it.next().getName());
                        }
           }
       
}


class comp implements Comparator<Person>
{
        public int  compare(Person p1,Person p2)
        {
            return  p1.getName().compareTo(p2.getName());
        }
}

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

6 个回复

正序浏览
徐帅 中级黑马 2012-5-25 20:49:15
7#
把视频又看了一遍,问题出在泛型上下限的问题上,开始以为比较器泛型可以接受自己和子类。
所以在打印函数中也可以接受自己和子类,事实是不同的集合有各自有自己的泛型上限或下限。
谢谢各位了!
回复 使用道具 举报
贠(yun)靖 发表于 2012-5-25 15:17
你那说的有点绝对了  值讨论语法的话,还是可以添加子类对象的

你说的对
应该说泛型里面的参数类型不讲继承和多态,要自己指定说明
public static void printCll(TreeSet<Person> al)为只能是TreeSet<Person>类型的参数
TreeSet<? extends Person>说明能传入TreeSet<Person>或TreeSet<Student>或TreeSet<Worker>类型的参数
回复 使用道具 举报
TreeSet<Worker> TreeSet<Student>传入的参数类型分别是 Worker、Student,传入到 printCll(TreeSet<Person> al),按照泛型的定义这里只接受Person类型,因为这里并不能完成Worker、Student到Person的转换。不同于 Iterator<Person>  it = al.iterator();
回复 使用道具 举报
niceBoy 发表于 2012-5-25 14:49
泛型里面的类型不讲继承和多态,只说明能是类型
TreeSet只是保存Student类型
TreeSet只保存Worker


你那说的有点绝对了  值讨论语法的话,还是可以添加子类对象的  
回复 使用道具 举报
泛型里面的类型不讲继承和多态,只说明能是类型
TreeSet<Student>只是保存Student类型
TreeSet<Worker>只保存Worker
TreeSet<Person>只保存Person
TreeSet<? extends Person>说明可以保存Person或者Person类的子类

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报

回帖奖励 +2

public static void printCll(TreeSet<? extends Person> al)
            {
                         Iterator<? extends Person>  it = al.iterator();
                         while (it.hasNext())
                         {
                                 System.out.println(it.next().getName());
                         }
            }
         

TreeSet<? extends Person> 是受限制通配符,此处的问号,代表一个未知的类型,这个未知的类型是Person的一个子类也可以使Person本身。可以把Person当成这个通配符的上限。

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马