ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一。你可以从这里查看全部的Java面试系列。

这篇文章介绍的常见面试题是关于重载(overloading)方法和重写(overriding)方法的。

Q.下面代码片段的输出结果是什么?

 public class MethodOverrideVsOverload {
public boolean equals( MethodOverrideVsOverload other ) {
System.out.println("MethodOverrideVsOverload equals method reached" );
return true;
} public static void main(String[] args) {
Object o1 = new MethodOverrideVsOverload();
Object o2 = new MethodOverrideVsOverload();
MethodOverrideVsOverload o3 = new MethodOverrideVsOverload();
MethodOverrideVsOverload o4 = new MethodOverrideVsOverload(); if(o1.equals(o2)){
System.out.println("objects o1 and o2 are equal");
} if(o3.equals(o4)){
System.out.println("objects o3 and o4 are equal");
}
}
}

A.输出结果是:

MethodOverrideVsOverload equals method reached

objects o3 and o4 are equal

这个问题考察了哪些概念呢?

  • Java语言中,一个类只能从一个类中继承出来(也就是,单继承结构),如果没有显式的标明所继承自的类,那么自动继承自Object对象。
  • 大多数的非final对象类方法都会被子类重写(overridden):

public boolean equals(Object obj); // make note of this method

public int hashCode();

public String toString();

  • 重载方法在编译时起作用(例如,静态绑定),重写方法在运行时起作用(例如,动态绑定)。静态绑定意味着JVM在编译时决定调用的类或方法。而动态绑定时,JVM是在运行时决定调用的类或方法。动态绑定设计是多态的基础。更多了解编译时和运行时.
  • 子类中重写父类的对应方法必须遵循下面的规则:
参数 不可变(译者注:包括参数类型和个数)。
返回类型 不可变,除了协变返回类型或其子类型(covariant (subtype) returns)。
异常 子类中可以抛出更少的异常,但绝对不能抛出父类中没有定义的已检查异常。
访问权限 比父类中对应方法更宽松。
调用 运行时(也就是动态绑定),根据对象类型来决定调用的具体方法。

现在,再回头看上面的代码,MethodOverrideVsOverload 类中的”equals(MethodOverrideVsOverload other)” 方法并没有重写Object类中的”public boolean equals(Object obj)” 方法。这是因为其违背了参数规则,其中一个是MethodOverrideVsOverload 类型,而另一个是Object类型。因此,这两个方法是重载关系发生在编译时),而不是重写关系

因此,当调用o1.equals(o2)时,实际上调用了object类中的public boolean equals(Object obj)方法。这是因为在编译时,o1和o2都是Object类型,而Object类的equals( … )方法是比较内存地址(例如,Object@235f56和Object@653af32)的,因此会返回false。

当调用o3.equals(o4)时,实际上调用了MethodOverrideVsOverload 类中的equals( MethodOverrideVsOverload other )方法。这是因为在编译时,o3和o4都是MethodOverrideVsOverload类型的,因此得到上述结果。

接下来还可以怎么提问呢?

Q.那怎么解决上面的那个问题呢?

A.在Java5中,新增了注解,其中包括很好用的编译时注解(compile time annotations)@override,来保证方法正确的重写了父类方法。如果在上面的代码中添加了注解,那么JVM会抛出一个编译错误。

因此,解决的方法就是给MethodOverrideVsOverload  类的boolean equals( MethodOverrideVsOverload other )方法添加@override注解。这样的话编译时就会有错误抛出来提示开发者某个方法没有正确的重写父类方法。之后,还需要修改方法的参数,将其从MethodOverrideVsOverload变成Object,具体如下:

 public class MethodOverrideVsOverload {  

     @Override
public boolean equals( Object other ) {
System.out.println("MethodOverrideVsOverload equals method reached" );
return true;
} public static void main(String[] args) {
Object o1 = new MethodOverrideVsOverload(); //during compile time o1 is of type Object
//during runtime o1 is of type MethodOverrideVsOverload
Object o2 = new MethodOverrideVsOverload(); //during compile time o2 is of type Object
//during runtime o2 is of type MethodOverrideVsOverload
MethodOverrideVsOverload o3 = new MethodOverrideVsOverload();  //o3 is of type MethodOverrideVsOverload
 // during both compile time and runtime
MethodOverrideVsOverload o4 = new MethodOverrideVsOverload(); //o4 is of type MethodOverrideVsOverload
// during both compile time and runtime
if(o1.equals(o2)){
System.out.println("objects o1 and o2 are equal");
}
if(o3.equals(o4)){
System.out.println("objects o3 and o4 are equal");
}
}
}

输出为:

MethodOverrideVsOverload equals method reached

objects o1 and o2 are equal

MethodOverrideVsOverload equals method reached

objects o3 and o4 are equal

上面的代码中,运行时equals方法正确的重写了Object中的相应方法。这是一个比较容易混淆的问题,面试的时候需要很详尽的解释相关的概念。

扩展阅读:

-- 扫描加关注,微信号: importnew --

英文原文: Java Success,编译:ImportNew - 郑雯

译文链接:http://www.importnew.com/2228.html

【如需转载,请在正文中标注并保留原文链接、译文链接和译者等信息,谢谢合作!】

【转】常见Java面试题 – 第三部分:重载(overloading)与重写(overriding)的更多相关文章

  1. Java中重载(overloading)和重写(Overriding)的区别

    一:方法的重载 (1)方法重载指在类中定义方法名相同,参数不同的不同的多个方法(返回值类型可随意,不能以返回类型作为重载函数的区分标准). 参数不同表现: 1.参数的个数不同 2.参数的类型不同 3. ...

  2. Python笔记_第三篇_面向对象_3.重载(overloading)和重写(overriding)

    1. 重载: overloading:就是将函数重新定义一遍. 1.1 __str__( )和__repr__( )的重载: 格式: __str__( ):在调用print打印对象时自动调用,是给用户 ...

  3. 【转】常见Java面试题 – 第四部分:迭代(iteration)和递归(recursion)

    ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一.你可以从这里查看全部的Java面试系列. Q.请写一段代码来计算给定文本内字符“A”的个数.分别用迭代和递归两种方 ...

  4. 【转】常见Java面试题 – 第二部分:equals与==

    ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一.你可以从这里查看全部的Java面试系列. Q2.下面的代码片段的输出是什么? Object s1 = new St ...

  5. 【转】常见Java面试题 – 第一部分:非可变性(Immutability)和对象引用(Object reference)

    ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一.请看此系列相关面试题.你可以从这里查看全部的Java面试系列. 一些比较核心的Java问题经常会用来考验面试者的J ...

  6. 【面试必备】常见Java面试题大综合

    一.Java基础 1.Arrays.sort实现原理和Collections.sort实现原理答:Collections.sort方法底层会调用Arrays.sort方法,底层实现都是TimeSort ...

  7. JAVA中继承时方法的重载(overload)与重写/覆写(override)

    JAVA继承时方法的重载(overload)与重写/覆写(override) 重载-Override 函数的方法参数个数或类型不一致,称为方法的重载. 从含义上说,只要求参数的个数或参数的类型不一致就 ...

  8. 转载文章 208 个最常见 Java 面试题全解析

    最近正值春招,一直在给公司招聘 Java 程序员,我从 2015 年做 TeamLeader 开始就习惯性地收集平时遇到的 Java 技术问题或周围朋友见过的面试题,经过不断筛选,终于凝练成一套实用的 ...

  9. BATJ的常见java面试题

    JAVA基础 JAVA中的几种基本数据类型是什么,各自占用多少字节. String类能被继承吗,为什么. 不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允 ...

随机推荐

  1. codeforces1238-div2

    C 目前在h的高度,1~h每一个台阶要么处于out的状态,要么处于in的状态,问最少改变几个台阶的状态,使得能够从h的高度到0. 下降的唯一的方式,拉动lever,h-1的状态取反,下落的最大的高度不 ...

  2. git 删除时报 the branch is not fully merged 这是什么意思

    今天删除本地分支 git branch -d XX 提示: the branch XXX is not fully merged原因:XXX分支有没有合并到当前分支的内容 解决方法:使用大写的D 强制 ...

  3. H3C 启动包过滤防火墙功能

  4. Vue v-if和v-show的使用.区别

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. H3C RIP基本配置举例

  6. Windows 服务安装与卸载 (通过 Sc.exe)

    1. 安装 新建文本文件,重命名为 ServiceInstall.bat,将 ServiceInstall.bat 的内容替换为: sc create "Verity Platform De ...

  7. Channel 9视频整理【6】

    GiGi Huang https://channel9.msdn.com/Niners/GiGiHuang

  8. springmvc整合freemarker教程(转)

    1.介绍 我最近喜欢freemarker在网上找了大半天.都没有找到一个简单又容易理解的案例.虽然只是一个模板技术.但是相对刚开始什么都不知道的,很难入手.下面是自学(其实是谷歌和百度的东找西补).写 ...

  9. freemarker<一>

    FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写.FreeMarker被设计用来生成HTMLWeb页面,特别是基于MVC模式的应用程序. 所谓模板,就是一份已 ...

  10. Python_自定义关键字的使用

    1.在Python中新建一个套件MOSAPP(一般为APP名称):New Suite→Directory 2.在套件下新建个资源文件My:New Resource:My 3.在My资源文件库下新建个关 ...