当前位置:  开发笔记 > 编程语言 > 正文

Java动态绑定和方法覆盖

如何解决《Java动态绑定和方法覆盖》经验,为你挑选了4个好方法。

昨天我接受了两个小时的技术电话采访(我通过了,哇喔!),但我完全消除了关于Java中动态绑定的以下问题.这让我感到非常困惑,因为几年前,当我还是TA时,我曾经向大学生传授这个概念,所以我给他们错误信息的前景有点令人不安......

这是我给出的问题:

/* What is the output of the following program? */

public class Test {

  public boolean equals( Test other ) {
    System.out.println( "Inside of Test.equals" );
    return false;
  }

  public static void main( String [] args ) {
    Object t1 = new Test();
    Object t2 = new Test();
    Test t3 = new Test();
    Object o1 = new Object();

    int count = 0;
    System.out.println( count++ );// prints 0
    t1.equals( t2 ) ;
    System.out.println( count++ );// prints 1
    t1.equals( t3 );
    System.out.println( count++ );// prints 2
    t3.equals( o1 );
    System.out.println( count++ );// prints 3
    t3.equals(t3);
    System.out.println( count++ );// prints 4
    t3.equals(t2);
  }
}

我断言输出应该是重写equals()方法中的两个单独的print语句:at t1.equals(t3)t3.equals(t3).后一种情况是显而易见的,并且对于前一种情况,即使t1具有Object类型的引用,它也被实例化为类型Test,因此动态绑定应该调用该方法的重写形式.

显然不是.我的采访者鼓励我自己运行程序,并且看,只有一个输出来自被覆盖的方法:在线t3.equals(t3).

我的问题是,为什么?正如我已经提到的,即使t1是Object类型的引用(因此静态绑定将调用Object的equals()方法),动态绑定应该负责根据引用的实例化类型调用方法的最具体版本.我错过了什么?



1> Robin..:

Java对重载方法使用静态绑定,对重写方法使用动态绑定.在您的示例中,equals方法被重载(具有与Object.equals()不同的参数类型),因此被调用的方法在编译时绑定到引用类型.

这里有一些讨论

它是equals方法的事实并不是真正相关的,除了它是一个常见的错误,超载而不是覆盖它,你已经知道这是基于你在面试中对问题的回答.

编辑:这里也有很好的描述.此示例显示了与参数类型相关的类似问题,但由同一问题引起.

我相信如果绑定实际上是动态的,那么调用者和参数是Test的一个实例的任何情况都会导致被调用的方法被调用.所以t3.equals(o1)将是唯一不会打印的情况.


@Override注释存在的另一个原因.
我的错误完全忽略了这个方法确实超载而不是被覆盖的事实.我看到"equals()"并立即认为继承和覆盖.看起来像我,再次,更广泛和更难的概念是正确的,但搞砸了简单的细节.:P

2> erickson..:

equals方法Test不会覆盖该equals方法java.lang.Object.看一下参数类型!所述Test类被重载equals用一个接受的方法Test.

如果equals要覆盖该方法,则应使用@Override注释.这会导致编译错误指出这个常见错误.



3> Benson..:

有趣的是,在Groovy代码(可以编译为类文件)中,除了一个调用之外的所有代码都将执行print语句.(将Test与对象进行比较的人显然不会调用Test.equals(Test)函数.)这是因为groovy会完全动态键入.这尤其令人感兴趣,因为它没有任何明确动态类型的变量.我已经在几个地方读到这被认为是有害的,因为程序员期望groovy做java事情.



4> Uri..:

Java不支持参数的协方差,仅支持返回类型.

换句话说,虽然重写方法中的返回类型可能是重写方式中的返回类型,但参数不是这样.

如果Object中的equals参数是Object,那么在子类中放置一个等于其他任何东西将是重载的,而不是重写的方法.因此,调用该方法的唯一情况是当参数的静态类型为Test时,如T3的情况.

祝你的面试过程顺利!我很乐意接受一家公司的采访,这家公司会询问这些类型的问题,而不是我教给学生的通常的算法/数据结构问题.

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有