文档章节

常见Java面试题 – 第三部分:重载(overloading)与重写(overriding)

crossbell
 crossbell
发布于 2014/06/03 19:18
字数 1077
阅读 17
收藏 0

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中的相应方法。这是一个比较容易混淆的问题,面试的时候需要很详尽的解释相关的概念。

本文转载自:http://www.importnew.com/2228.html

共有 人打赏支持
crossbell
粉丝 25
博文 172
码字总数 14545
作品 0
海淀
项目经理
阿里巴巴菜鸟Java一面11个问题,你会几个呢?

近日,w3cschool app开发者头条上分享了阿里菜鸟Java程序员一些面试题。 这吸引了不少程序员小伙伴们的注意。 在分享阿里菜鸟Java程序员面经前,来看下Java面试一些面试经验分享: 0、Java高...

W3Cschool
04/03
0
0
Java 的重写(Overriding)与重载(Overloading)

方法重载: (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。 重载Overloading是一个类中多态性的一种表现。 (2) Java的方法...

和蔼的哔哔
2015/08/19
0
0
JAVA面试题总结(SE部分)

Person p = new Person(); 创建一个对象都在内存中做了什么事情? 1:先将硬盘上指定位置的Person.class文件加载进内存。 2:执行main方法时,在栈内存中开辟了main方法的空间(压栈-进栈),然...

期待变强的菜鸟
2014/03/16
0
1
Java中的静态绑定和动态绑定

在Java中,当你调用一个方法时,可能会在编译时期解析,也可能实在运行时期解析,这全取决于到底是一个静态方法还是一个虚方法。如果是在编译时期解析,那么就称之为静态绑定,如果方法的调用...

t_yapeng
2017/10/26
0
0
金九银十,史上最强 Java 面试题整理。

以下会重新整理所有 Java 系列面试题答案、及各大互联网公司的面试经验,会从以下几个方面汇总,本文会长期更新。 Java 面试篇 史上最全 Java 面试题,带全部答案 史上最全 69 道 Spring 面试...

Java技术栈
09/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

74.expect脚本同步文件以及指定host同步文件 构建分发系统文件和命令

20.31 expect脚本同步文件: 在expect脚本中去实现在一台机器上把文件同步到另外一台机器上去。核心命令用的是rsync ~1.自动同步文件 #!/usr/bin/expect set passwd "123456" spawn rsync -a...

王鑫linux
21分钟前
0
0
TypeScript项目引用(project references)

转发 TypeScript项目引用(project references) TypeScript新特性之项目引用(project references) 项目引用是TypeScript 3.0中的一项新功能,允许您将TypeScript程序构建为更小的部分。 通过这...

durban
25分钟前
0
0
爬虫入门

导读 网络爬虫(Web crawler),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本,它们被广泛用于互联网搜索引擎或其他类似网站,可以自动采集所有其能够访问到的页面内容,以获取...

问题终结者
25分钟前
0
0
ppwjs之bootstrap文字排版:无序列表项不换行

<!DOCTYPT html><html><head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><title>ppwjs欢迎您</title><link rel="icon" href="/favicon.ico" ......

ppwjs
32分钟前
0
0
SpringBoot 学习一

本文将从以下几个方面介绍: 前言 HelloWorld 读取配置文件 例子(CURD) 前言 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架...

tsmyk0715
32分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部