面试题答案
一键面试多态性体现
- 方法重载:在一个类中定义多个同名方法,但方法的参数列表不同(参数个数、类型或顺序不同)。它体现多态性是因为在编译期,编译器根据调用方法时传入的参数类型和个数来决定调用哪个重载方法,这是一种编译时多态。例如,在一个
MathUtil
类中定义add(int a, int b)
和add(double a, double b)
方法,根据传入参数类型决定调用哪个方法。 - 方法重写:子类重写父类中已有的方法,方法名、参数列表和返回值类型都必须相同(返回值类型在Java 5.0后可以是协变返回类型)。它体现多态性是在运行期,JVM根据对象的实际类型来决定调用哪个重写方法,这是运行时多态。例如,
Animal
类有void sound()
方法,Dog
类继承Animal
并重写sound()
方法,当Animal animal = new Dog(); animal.sound();
时,运行时会调用Dog
类的sound()
方法。
实现机制不同
- 方法重载:基于编译期的静态绑定。编译器在编译阶段,根据调用方法的参数列表,确定具体要调用的方法版本。因为在编译时就能确定调用哪个方法,所以效率相对较高。
- 方法重写:基于运行期的动态绑定。JVM在运行时,根据对象的实际类型(而不是声明类型)来确定调用哪个重写方法。JVM通过对象的虚方法表(vtable)来实现动态绑定,虚方法表存储了对象实际类型对应的方法地址,运行时根据对象在虚方法表中的记录找到要调用的方法。
应用场景不同
- 方法重载:用于为一个类提供多个功能类似但参数不同的方法,方便用户调用。比如
System.out.println()
方法就有多个重载版本,可接受不同类型参数,便于输出不同类型的数据。 - 方法重写:用于子类根据自身需求对父类方法进行更具体的实现,以实现行为的定制化。例如在图形绘制系统中,
Shape
类有draw()
方法,Circle
类和Rectangle
类继承Shape
并重写draw()
方法,以实现各自图形的绘制。
运行时表现不同
- 方法重载:在编译时就确定调用哪个方法,运行时不会改变。所以在编译期如果参数类型不匹配会报错,例如调用不存在的重载方法会出现编译错误。
- 方法重写:运行时才根据对象实际类型确定调用的方法。如果子类对象被当作父类类型处理,运行时会调用子类重写的方法,而不是父类的原始方法。例如
Animal animal = new Dog();
,animal.sound()
调用的是Dog
类重写后的sound()
方法。