List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
System.out.println(list);//结果输入   [1, 2, 3] 根据多态性  list对象调用方法时 只能调用List接口中定义的或从父接口中继承的方法
其中toString()好像不在其和其父接口之中吧  
为什么 
System.out.println(list)时会输出

解决方案 »

  1. java 中所有的类都是从object 中继承来的。
    而toString是Object类的方法。
      

  2. List 不是类  它是个接口 另外看API文档也能看出来  一般的下面会写出 从xxx类继承的方法  
    在 java.util.List 下没有  
      

  3. System.out.println(list);
    //等同于
    System.out.println(list.toString());
    /*
    这里面的list.toString()方法,实际上,调用的是
    ArrayList对象的toString()方法。
    */首先,List接口没有toString方法,所以,问题不在List接口上。
            你调用的toString方法不是List要求实现的方法。
    其次,在Java当中,所有的类,都默认继承Object类,并且,Object类中,有toString方法。
            ArrayList作为一个类,也默认继承Object类,并且,实际当中,它重写了toString方法。
    最后,调用toString方法,并没有展现List的多态性,而是Object的多态性。
            其默认的toString实现,是返回JVM的对象地址,但是,很多对象都重写该方法,从而表现不同。
            比如:Integer返回的是数字内容;StringBuilder返回的是当前缓冲区内存放的字符串;
                    ArrayList返回的是当前集合当中所有对象的toString结果;等等。
      

  4. List list = new ArrayList();list是ArrayList对象,是List的引用,
    List是抽象的,当然没办法实例化。
    作为ArrayList对象,继承自Object类,自然有toString方法。
      

  5. 所有的关键是  System.out.println(list); 输出即 说明list.toString() 成立 问题就出在这
    明明java.util.List 中没有  toString()  却还是能执行 我再说个吧  
    Collection list = new ArrayList();
    list.add(1);
    list.add(2);
    list.add(3);
    System.out.println(list.toString());这个的输出结果也是 [1, 2, 3]  然而如果你调用 ArrayList 中的get()方法 
    即list.get(index) 就会出错  
    原因是 The method get(int) is undefined for the type Collection这个情况 难道和 list.toString() 有什么不一样的地方吗 不应该都是  没有定义该方法吗
      

  6. 万物皆对象,都继承了object类
    所以也就重载了object的toString()方法
      

  7. 既然楼主小盆友了解多态,那回答这个问题就太简单了。
    你可以查看JDK API文档,
    能够发现ArrayList对象的继承关系如下:
    java.util 
    Class ArrayList<E>
    java.lang.Object
      java.util.AbstractCollection<E> (找到toString(),所以ArrayList调用的是此方法)
          java.util.AbstractList<E> (未找到toString()方法,继续上推)
              java.util.ArrayList<E>
    其中抽象类AbstractCollection的重写了Object对象的toString方法,代码如下:public String toString()
        {
            StringBuffer stringbuffer = new StringBuffer();
            stringbuffer.append("[");
            Iterator iterator1 = iterator();
            boolean flag = iterator1.hasNext();
            do
            {
                if(!flag)
                    break;
                Object obj = iterator1.next();
                stringbuffer.append(obj != this ? String.valueOf(obj) : "(this Collection)");
                flag = iterator1.hasNext();
                if(flag)
                    stringbuffer.append(", ");
            } while(true);
            stringbuffer.append("]");
            return stringbuffer.toString();
        }
      

  8.  
    java.util.AbstractCollection<E> (找到toString(),所以ArrayList调用的是此方法)
    java.util.AbstractList<E>  这个对List接口实现了AbstractList<E> 
    AbstractList<E>继承自AbstractCollection<E> 有toString 方法。Collection 类并没有get方法。list.get()
    Collection类的引用list自然无法调用get()方法了。
      

  9. 顺便问句:
    List list = new ArrayList();
    list.get()是会调用ArrayList里面的get方法吧?
    因为引用list指向的是ArrayList对象,
    是不是多态有什么法则的。
      

  10. List list = new ArrayList();
    list.add(1);
    list.add(2);
    list.add(3);
    System.out.println(list);
    在打印的时候虚拟机会自己去调用.toString()方法;
    toString()方法是Object对象的一个方法,所有类都直接或者间接的继承他,而且你不写他默认继承,
      

  11. Collection是一个接口,是不会也不可能重写Object对象的toString方法的。
    我所列出JDK源码中ArrayList的继承关系已经说的非常清楚了。
    AbstractCollection<E>是一个抽象类,它重写了toString方法。
      

  12. 哥唉  
    Collection list = new ArrayList();
    list.add(1);
    list.add(2);
    list.add(3);
    System.out.println(list.toString());
    输出结果为 [1, 2, 3]   Collection list = new ArrayList();
    list.add(1);
    list.add(2);
    list.add(3);
    System.out.println(list.get(1));
    会报错  The method get(int) is undefined for the type Collection红色标记的两个方法是不是在 ArrayList 中或其父类中都有 
    为什么第一个对   第二个却 说没有这个方法这不是多态的范畴吧
    要是正常的多态 应该是 上面两个都会报 没有该方法 的错误
      

  13. 举了一个例子,算是对JDK API的简要说明吧,情况相似。//相当于Collect类
    public interface InterfaceA {}//AbstractB(相当于那个AbstractCollect类)实现InterfaceA
    public abstract class AbstractB implements InterfaceA {
    public String toString(){//覆盖Object的方法
    return "AbstractB";
    }
    }public class ClassC implements InterfaceA{

    public static void main(String[] args) {
    InterfaceA cc=new ClassC();
    System.out.println(cc.toString()); //调用的是Object的方法(因为ClassC隐含继承Object)
    //cc.get(); //报错,因为Object和InterfaceA中都找不到
    }
    }public class ClassD extends AbstractB{

    public static void main(String[] args) {
    InterfaceA dd=new ClassD();
    System.out.println(dd.toString()); //调用的是AbstractB的方法()
    //dd.get(); //报错,因为Object和AbstractB及InterfaceA中都找不到
    }
    }很明显ClassD和ArrayList的继承关系相似,而非ClassC.
    JDK API中也指出了抽象类AbstractCollect实现了Collect接口。
      

  14. 首先,回答lz的问题;能够进行输入,是因为所有的toString()是Object的方法。而Object是所有类的基类;
    二是,涉及到了多态。因为每个类的toString()实现方法不一样,不过这个和lz要的结果没有关系。
      


  15. Collection接口没有get方法
    List接口有
    ArrayList实现了这两个接口
      


  16. public class ClassD extends AbstractB{
        
        public static void main(String[] args) {
            InterfaceA dd=new ClassD();
            System.out.println(dd.toString()); //调用的是AbstractB的方法()
            //dd.get(); //报错,因为Object和AbstractB及InterfaceA中都找不到
        }
    }其实AbstractB也隐含继承Object.但它重写了toString方法。
    又由于接口和抽象类都是不能实例化的,所以使用更上层的接口做为超类声明时,最终的具体子类在初始化时,都会先递归完成所有祖先类的初始化工作。在最终方法的调用时,如果自身不存在,则通过逐层查找,总是查找最近层父类中的相关方法。如果追到源头Object也没有,那就真没有了。
      

  17. List不是类·但是ArrayList是类··别弄错了··竟然它是个类·那就一定继承与Object``所以··使用的还是Object的toString()方法··
      

  18. 第二个地方报错我想是因为你定义list的时候运用了多态,导致list.get()方法返回的是一个泛型··泛型自然是不能直接输出的
      

  19. 楼主说的是个问题,list只是个接口,没有定义toString方法,但却最终调用了。
    这里有一点新东西,好像是没有语法书上写出来的(也可能是我读的太少吧),但我通过实验得出来以下结论。
    那就是,如果一个接口被实例化,那么,这个接口将自动继承object类中未被重写的方法。
    以你的代码中的list为例,该接口最终不仅拥有toString()方法,而且还拥有object类当中的
    三个wait方法以及notify(),notifyAll(),getClass()方法。
    list接口当中总共25个方法,但是在本次代码中,实例化之后,却拥有了32个方法,增加的七个方法正是如上所述的七个方法。
    但是为什么object当中还有clone,和finalize方法没有被list继承呢?我想应该是因为ArrayList类或者它的父类已经将该方法实现。
    所以我的结论是“这个接口将自动继承object类中未被重写的方法”
    注:实验工具Eclipse自动补充解析功能
      

  20. 问了一下ZantXT大哥,了解了一下真相:接口调用Object中定义的方法,是jvm直接支持的。
    所以:
    用Collect声明时,ArrayList对象调用的不是接口调用的Object中的toString,而是调用的AbstractCollect中重写的方法。
    由超类声明,子类来new.调用的最终是子类中定义的方法,如果子类没有,则调用父类方法。
    这存在一种向上追溯的过程。
    这也就是为什么Collect下还有一个抽象类AbsctratCollect这仍是多态的表现。故:
    我重新支持自己在20楼及23楼中的说法。
    24楼的话取消。
      

  21. 这句应该是对的 因为 输出的 结果的形式和 AbstractCollect中重写的toString()的形式一样。这句话 不完全对 只能是调用子类中重写超类的方法 引用一下你写的例子说明一下
    //相当与Collection
    public interface InterfaceA {}//AbstractB(相当于那个AbstractCollect类)实现InterfaceA
    public abstract class AbstractB implements InterfaceA {
        public String toString(){//覆盖Object的方法
            return "AbstractB";
        }
        
        public void get(){
         System.out.println("AbstraceB get()");
        }
    }
    //相当于ArrayList
    public class ClassD extends AbstractB{
        
        public static void main(String[] args) {
            InterfaceA dd=new ClassD();        System.out.println(dd.toString()); //调用的是AbstractB的方法()
            dd.get(); //报错,因为Object和AbstractB及InterfaceA中都找不到
        }
    }InterfaceA中没有定义get()  AbstractB 中定义了get()  ClassD 中调用get()会报错 InterfaceA dd=new ClassD();
    dd.get(); //这次在AbstractB 中可以找到了吧编译时dd只能看见InterfaceA中定义的和其父和祖宗接口中声明的方法 因为之中没有 get() 所以报错。虽然AbstractB 中有get()  ClassD继承AbstractB 又能怎样 
    在本例中 ClassD中没有get() 它可以调用AbstractB 中的get()的前提是 InterfaceA 中或祖宗接口中有get()的声明
    如果没有 连编译这一关就过不了相比之下
    InterfaceA中没有声明 toString() 且它的父接口和祖宗接口中也没定义可以看API 
    却可以通过编译而且执行所以我觉得吧 Object这个类 还有它中的方法 反正就是不能按常理来推 比较特殊 里面肯定有更深的东西。
    要么就是 我对多态的理解还不够 
      

  22. 28楼的朋友  说的情况我见过  用Eclipse 时 确实会 弹出Object中的 方法可能接口都默认的继承Object吧 要么就是  JVM干的好事反正API  上是没有 表明 它继承了 Object
      


  23. 楼主懂得思考,先表扬一下。下面将引用一段接口的说明,你可以看看:9.2 Interface Members
    The members of an interface are:Those members declared in the interface. 
    Those members inherited from direct superinterfaces. 
    If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.
      

  24. 大致意思如下:9.2 接口方法
      一个接口中的方法有:
      1).直接声明在接口中的成员方法;
      2).直接从父类接口中继承而来的方法;
      3).如果一个接口没有直接的父类接口(也就是其自身就是顶层接口),并且在其没有显示声明相关方法时,那该接口则会根据Object中所有的public的实例方法进行一一映射(比如toString,Hashcode等)。当然如果此接口显示去声明一个与Object签名相同并且带有final修饰的方法时,则会有编译期错误。
      

  25. 所以:由超类声明,子类来new.调用的最终是子类中定义的方法,如果子类没有,则调用父类方法。
    这存在一种向上追溯的过程。
    的说明是完全正确的。
      

  26. 完全赞同!
    这里做一点补充。
    根据这一条说明,在List list=new ArrayList()之后,在list当中将可以调用object当中所有声明public的方法,而调用的方法实体是来自ArrayList的。而之所以没有list不可以调用,clone()与finalize()方法,只是因为它们是protected的。
    学习了。
    不过很好奇,33楼的大哥,这条如此原版的声明出自哪个参考书籍呢?学java就该看这种资料啊。
      

类似问题 »