重载(overloading)与重写(overriding)
英文原文: Java Success,编译:ImportNew - 郑雯
ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一。你可以从这里查看全部的Java面试系列。
这篇文章介绍的常见面试题是关于重载(overloading)方法和重写(overriding)方法的。
Q.下面代码片段的输出结果是什么?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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,具体如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
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中的相应方法。这是一个比较容易混淆的问题,面试的时候需要很详尽的解释相关的概念。
相关推荐
在编程语言中,方法重载(Overloading)和方法重写(Overriding)是两个非常重要的概念,它们都是实现多态性(Polymorphism)的关键机制。本文将深入探讨这两个概念,以及它们在实际编程中的应用。 ### 方法重载...
重载Overloading是一个类中多态性的一种表现。在Java中,方法重载就是在类中创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用...
重载Overloading是一个类中多态性的一种表现。 (2) Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。 调用方法时通过传递给它们的不同参数个数和参数...
重载Overloading是一个类中多态性的一种表现。Java 中的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体...
在Java编程语言中,方法的重载(Overloading)与重写(Overriding)是两个非常重要的概念。它们虽然只有一字之差,但其实质却大相径庭。理解这两者的不同对于深入掌握Java语言至关重要。 ### 一、重载(Overloading...
Java中的重载(Overloading)和重写(Overriding)是面向对象编程中两个重要的概念,它们体现了Java的多态性。多态性是面向对象编程的三大特性之一,另外两个是封装和继承。 首先,让我们详细解释一下方法的重载。重载...
### C++中重载、重写(覆盖)与隐藏的概念及区别 #### 一、引言 在C++面向对象编程中,理解重载、重写(覆盖)以及隐藏的概念至关重要。这些概念不仅有助于我们更好地设计类和继承体系,还能帮助我们避免一些常见的...
### C++中重载与重写函数的区别及虚函数详解 #### 一、虚函数概述 **1.1 虚函数定义与作用** 在C++中,虚函数是一种特殊的成员函数,它允许子类覆盖父类的行为。虚函数的核心在于实现多态性,即在运行时动态决定...
Java 中的重载(Overloading)与重写(Overriding)是两个重要的概念,它们都是实现多态性的重要方式,但两者之间存在着显著的区别。 **重载(Overloading)** 重载是指在同一个类中可以有多个同名方法,但这些...
Java编程语言中,方法的两种重要特性是方法重载(Overloading)和方法重写(Overriding)。这两种机制都是为了实现多态性,但它们在实际应用中有着明显的区别。 **方法重载(Overloading)**: 方法重载发生在同一...
在面向对象编程中,方法的重写(Overriding)和重载(Overloading)是非常重要的概念。这两种机制可以帮助程序员更灵活地管理和组织代码,提高代码的复用性和可扩展性。 #### 二、重载(Overloading) **定义:** ...
Java中的重载(Overloading)和重写(Overriding)是面向对象编程中的两种关键特性,它们涉及到方法的多态性。理解这两者的区别对于编写高效、可维护的代码至关重要。 **重载(Overloading)**是指在一个类中,可以有多个...
Java 中的重载(Overloading)和重写(Overriding)是两个重要的概念,它们都是实现多态性的重要方式,但两者之间存在着显著的区别。 **重载(Overloading)** 重载是同一个类中不同方法的实现,这些方法拥有相同...
Java 中的重载(Overloading)和重写(Overriding)是两个非常重要的概念,它们都是多态性的体现形式。 一、Java 中的重载(Overloading) Java 中的重载是指在同一个类中可以创建多个方法,它们具有相同的名字,...
在 Java 编程语言中,方法的重载(Overloading)和重写(Overriding)是面向对象编程的重要概念。这两种技术使得方法能够在不同的上下文中表现出不同的行为,从而增强了代码的灵活性和可读性。下面将深入探讨 Java ...
重写(Overriding)是指子类可以提供与父类相同签名的方法,但提供不同的实现。重写只发生在继承关系中,子类方法必须声明为`@Override`(在Java中),以确保该方法确实覆盖了父类的相应方法。在运行时,如果对象是...
重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。Overloaded的方法是可以改变返回值的类型。也就是说,重载的返回值类型可以相同也可以不同。 重载(Overloading) a、...
JAVA重写和重载(Overriding和Overloading) JAVA中有两种不同的多态性表现形式:重写(Overriding)和重载(Overloading)。下面将对这两种形式进行详细的解释。 重载(Overloading) 重载是指在一个类中可以...
Java编程语言中的重载(Overloading)和重写(Overriding)是两个关键的概念,它们都是多态性的重要体现,但各自有着不同的含义和规则。 首先,我们来详细了解一下方法的重载。重载,简单来说,就是在一个类中定义多个...