如果接口引用一个子类对象(实现了它的),而接口里没有定义toString()方法,怎么调用这个引用的对象里的toString()方法?如:Map m=new HashMap();
System.out.println(m);假设已经给m赋值,为什么打印出来的是用的HashMap类里的toString()方法???用接口引用,m看成Map类型的,但是toString()在Map接口里没定义呀?m只能调用接口定义的方法和常量呀?即只能调用继承或实现的方法和属性,子类新增的方法不能调用。请高手给解答一下。

解决方案 »

  1.   

    楼主要知道,接口里面没有任何实现,所以调用接口对象的方法,实际上就是调用这个接口的某个实现类的方法。楼主的代码很明白了,变量 m 是一个 Map 接口对象,而这个对象的实现类是 HashMap。所以当调用 Map 的 toString() 方法时,系统根据这个变量的实际类型,调用了 HashMap 的 toString() 方法。注意,Map 接口并没有实现任何方法。
      

  2.   

    Map中没有定义,但是它们都是Object的子类,而Object中有toString() 的定义.它们应该是调用的Ojbect()继承的toString()这是一种多态的表现.
    m定义为一个Map ,而它实际上指向的是 HashMap()  ,
    从语法上来讲,编译器会把它作为一个Map的对象看, 这种情况下,如果调用了子类独有的方法,
    首先编译器都不能通过编译.而可以调用父接口已经定义的方法的原因是 : java的动态多态的表现, 它还是把m做为一个Map看待,
    只是在运行的时候,具体找到了该引用在内存中的HashMap实例的内存地址,从而调用了该内存块中的和你接口同名的方法或者属性.
      

  3.   

    答:楼主显然对搂口的理解还不全面.
    在JLS9.2节中接口中的成员方法讲得很明确,基本的是说:接口中的抽象方法来源有两类:
    1)你自己定义的抽象方法
    2)类Object中的public型方法迁移过去的方法(以public abstract形式--即:抽象方法)因此:显然Map接口中当然的抽象方法public abstract String toString();这个抽象方法的.(Object中的public型方法,Map接口中都有)
      

  4.   

    1.如果 A 类实现了 B 接口,在使用 B 引用 A 类对象时,只能使用 B 接口所提供的方法、属性,A 类新增的方法、属性,是不能使用的,
    因为 B test = new A();
    这个操作的时候,其实已经隐式地,向上转型了
      

  5.   

    HashMap也是没有覆写toString()的
    Map,HashMap都继承了类java.util.AbstractMap
    AbstractMap类覆写了Object类的toString()方法
      

  6.   

    谢谢大家的回答,对我都很有帮助。2楼的多态我认为很有道理;但是3楼的迁移规则似乎更有说服力,只是我没有这样的资料;麻烦问下JLS是什么书?
      

  7.   

    AbstractMap是实现了Map接口,不是Map继承的AbstractMap
      

  8.   

    答:JLS就是<<JAVA语言规范>>,最最权威的书了.有疑问,就找它.
      

  9.   

    衷心感谢,另外发现又有对2楼回答的疑问,请2楼回答:如果是多态的话,应该是父类里有的方法被子类继承了,再覆写。可是现在Map接口里没有定义toString()方法,何来多态?除非有其他原因,这就是我对2楼回答的疑问。谢谢。
      

  10.   

    答:因此,能否调用toString()方法,与多态是一点关系都没有的.
      

  11.   

    Object---->Map,故Map有toString()
    这个就是个动态绑定(多态)