黑马程序员技术交流社区

标题: 关于泛型扩展的一个小问题 [打印本页]

作者: 徐帅    时间: 2012-5-25 13:04
标题: 关于泛型扩展的一个小问题
为什么已经继承了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());
        }
}

作者: 乔建国    时间: 2012-5-25 14:27
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当成这个通配符的上限。
作者: niceBoy    时间: 2012-5-25 14:49
泛型里面的类型不讲继承和多态,只说明能是类型
TreeSet<Student>只是保存Student类型
TreeSet<Worker>只保存Worker
TreeSet<Person>只保存Person
TreeSet<? extends Person>说明可以保存Person或者Person类的子类

作者: 贠(yun)靖    时间: 2012-5-25 15:17
niceBoy 发表于 2012-5-25 14:49
泛型里面的类型不讲继承和多态,只说明能是类型
TreeSet只是保存Student类型
TreeSet只保存Worker


你那说的有点绝对了  值讨论语法的话,还是可以添加子类对象的  
作者: 黑马11期李项京    时间: 2012-5-25 15:33
TreeSet<Worker> TreeSet<Student>传入的参数类型分别是 Worker、Student,传入到 printCll(TreeSet<Person> al),按照泛型的定义这里只接受Person类型,因为这里并不能完成Worker、Student到Person的转换。不同于 Iterator<Person>  it = al.iterator();
作者: niceBoy    时间: 2012-5-25 15:43
贠(yun)靖 发表于 2012-5-25 15:17
你那说的有点绝对了  值讨论语法的话,还是可以添加子类对象的

你说的对
应该说泛型里面的参数类型不讲继承和多态,要自己指定说明
public static void printCll(TreeSet<Person> al)为只能是TreeSet<Person>类型的参数
TreeSet<? extends Person>说明能传入TreeSet<Person>或TreeSet<Student>或TreeSet<Worker>类型的参数
作者: 徐帅    时间: 2012-5-25 20:49
把视频又看了一遍,问题出在泛型上下限的问题上,开始以为比较器泛型可以接受自己和子类。
所以在打印函数中也可以接受自己和子类,事实是不同的集合有各自有自己的泛型上限或下限。
谢谢各位了!





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