这篇文章介绍的常见面试题是关于重载(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中的相应方法。这是一个比较容易混淆的问题,面试的时候需要很详尽的解释相关的概念。
相关推荐
方法的重写(Overriding)是父类与子类之间多态性的一种表现,重载(Overloading)是一个类中多态性的一种表现。 重写 Overriding 是指子类重新定义从父类继承来的方法,实现自身的行为,而不是实现由父类定义的行为...
### 2024年Java基础面试题及解析 #### 1. 什么是 Java? **答案解析:** Java 是一种广泛使用的高级编程语言,由 Sun Microsystems 在 1995 年开发并发布。它的主要特点包括面向对象、平台独立性、安全性、可移植...
1. **Java中实现多态的机制**:Java通过方法的重写(Overriding)和重载(Overloading)实现多态性。重写是子类对父类方法的重新定义,使得子类对象可以拥有与父类不同的行为;重载则是同一个类中多个同名但参数列表...
4. 多态:多态体现在方法重载(overloading)和方法覆盖(overriding)上。方法重载是在同一类中,方法名相同但参数列表不同的方法;方法覆盖发生在子类中,子类重写父类的方法。 四、集合框架 1. List、Set和Map...
以下是对这些常见面试题的详细解释: 1. **List、Map、Set 的特点**: - **List**:有序列表,允许重复元素,如 ArrayList 和 LinkedList。 - **Set**:无序集合,不允许重复元素,如 HashSet 和 TreeSet。 - **...
### 最全Java面试题汇总(一):详细解析与知识点扩展 #### 1. Java面试题概述 本文将对一份“最全Java面试题汇总”中的部分题目进行详细解析,并结合实际应用场景,深入探讨相关知识点。 #### 2. 题目101:变量...
### Java面试题汇总知识点 #### 1. Java序列化 - **定义**:Java序列化是一种将对象状态转换成字节流的过程,以便于存储或网络传输。它使得对象能够跨进程、跨机器进行传递。 - **实现方式**:一个类如果想要实现...
### JAVA常见面试题300道之精选知识点解析 #### 1. Java 为何被称为平台无关的语言? Java 是一种能够跨平台运行的编程语言。它通过编译源代码(.java 文件)为字节码(.class 文件),使得在任何安装了 Java ...
### Java面试题总结 #### 一、面向对象的特征有哪些方面? 面向对象编程(OOP)是一种编程范式,它强调将程序结构组织成一组对象,每个对象都可以接收其他对象发送的消息、处理数据、以及执行动作。Java作为一种典型...
### 常见Java面试题解析 #### 1. 什么是Java虚拟机?为什么Java被称为“平台无关的编程语言”? **Java虚拟机(JVM)**是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被JVM执行的字节码文件。Java的...
### 最新最全Java面试题汇总 #### 1. Java中的访问控制修饰符:public, private, protected 及默认(friendly) 在Java中,我们有四种主要的访问控制级别,它们分别是 `public`、`private`、`protected` 和默认...
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数...
3. **方法重载(Overloading)与方法重写(Overriding)**:方法重载发生在同一类中,指的是有相同名称但参数列表不同的方法。方法重写发生在子类中,是指子类重新定义父类中已有的非私有方法,要求返回类型和方法名...
Java编程语言中的重载(Overloading)和重写(Overriding)是两个核心概念,它们在多态性中起着至关重要的作用。 **重载(Overloading)**:这是在同一类中实现多态的一种方式,通过创建多个具有相同名字但参数列表不同的...
### CoreJava面试题知识点解析 #### 1. final, finally, finalize 的区别 - **final**: 是Java中的关键字,用于标记常量、方法或类,表明这些元素是不可变的。当修饰变量时,该变量被称为常量,一旦被初始化就不能...
【Java面试核心知识点详解】 1. **Java内存管理与生命周期** Java内存主要分为栈内存、堆内存和方法区。...以上是Java面试中常见的核心知识点,掌握这些内容将有助于提升面试自信,有效应对各种面试挑战。
在Java编程语言中,面试题通常涵盖了许多核心概念和技术,以评估候选人的基础知识和实际应用能力。以下是对富士康JAVA面试题1中涉及的一些关键知识点的详细解释: 1. **字符串对象创建**: 当执行`String s = new ...
2. **方法重载(Overloading)和方法重写(Overriding)**:方法重载发生在同一类中,方法名相同但参数列表不同;方法重写发生在子类中,子类方法签名与父类方法完全一致,并且重写父类的行为。 3. **接口与内部类...