面试题答案
一键面试重载和重写在多态性中的角色
- 重载(Overloading)
- 角色:重载是指在一个类中定义多个同名方法,但这些方法的参数列表(参数个数、类型或顺序)不同。它是编译时多态的体现,通过方法名相同但参数列表不同,让类可以以多种方式处理不同类型或数量的输入。例如,一个
MathUtils
类中可以有add(int a, int b)
和add(double a, double b)
方法,它们都执行加法操作,但适用于不同的数据类型。重载增强了类的功能多样性,使代码更具可读性和可维护性。
- 角色:重载是指在一个类中定义多个同名方法,但这些方法的参数列表(参数个数、类型或顺序)不同。它是编译时多态的体现,通过方法名相同但参数列表不同,让类可以以多种方式处理不同类型或数量的输入。例如,一个
- 重写(Overriding)
- 角色:重写是指子类重新定义父类中已有的方法。重写后的方法必须与父类中被重写方法具有相同的方法签名(方法名、参数列表和返回类型,JDK 5.0 后返回类型可以是父类方法返回类型的子类)。重写是运行时多态的基础,它允许子类根据自身需求定制从父类继承来的行为。比如,
Animal
类有一个makeSound
方法,Dog
类继承自Animal
并重写makeSound
方法来发出狗叫声,Cat
类同样重写该方法来发出猫叫声。这样,不同子类对象调用相同方法名的方法时,会执行不同的具体行为。
- 角色:重写是指子类重新定义父类中已有的方法。重写后的方法必须与父类中被重写方法具有相同的方法签名(方法名、参数列表和返回类型,JDK 5.0 后返回类型可以是父类方法返回类型的子类)。重写是运行时多态的基础,它允许子类根据自身需求定制从父类继承来的行为。比如,
重写方法在运行时确定具体执行版本的机制(结合JVM运行时绑定)
- JVM的运行时绑定:JVM在运行时确定调用重写方法的具体版本,这一过程称为动态绑定或运行时绑定。当通过父类引用调用重写方法时,JVM会在运行时根据对象的实际类型(而不是引用类型)来确定要执行的方法版本。
- 具体过程:假设存在
Animal
类及其子类Dog
和Cat
。Animal animal = new Dog();
,这里animal
是Animal
类型的引用,但实际指向的是Dog
类的对象。当调用animal.makeSound()
时,JVM首先在Dog
类中查找makeSound
方法。如果Dog
类中定义了makeSound
方法(即重写了Animal
类中的makeSound
方法),则执行Dog
类中的makeSound
方法。如果Dog
类没有定义(但父类Animal
有),JVM会沿着继承链向上查找,直到找到该方法并执行。这是因为JVM在对象创建时,会在对象的内存布局中包含一个指向类元数据(包含方法表等信息)的指针。方法表中记录了类及其父类中定义的方法的实际地址。当调用重写方法时,JVM通过对象的实际类型找到对应的方法表,进而确定要执行的具体方法版本。
重载方法与运行时绑定的关系
- 重载与编译时绑定:重载方法在编译时确定调用的具体版本,属于编译时多态。编译器根据调用方法时提供的参数列表,在编译阶段就能够确定应该调用哪个重载版本的方法。例如,
MathUtils.add(1, 2)
,编译器根据参数类型int
,能够确定调用add(int a, int b)
这个重载方法。所以,重载方法与运行时绑定无关,它是在编译阶段由编译器完成方法选择的。