📅  最后修改于: 2023-12-03 14:42:55.978000             🧑  作者: Mango
在Java中,动态方法分派或运行时多态性是一种重要的特性,它可以让我们以更加灵活的方式编写代码,同时提高代码的可维护性和可扩展性。
动态方法分派是指在运行时根据实际类型调用相应的方法。具体来说,当一个对象调用一个方法时,编译器只能确定该对象的引用类型,而不能确定它的实际类型。因此,Java虚拟机会在运行时根据实际类型决定调用哪个方法。
例如,我们可以定义一个Animal
类和它的子类Dog
和Cat
:
class Animal {
public void makeSound() {
System.out.println("Animal is making sound.");
}
}
class Dog extends Animal {
public void makeSound() {
System.out.println("Dog is barking.");
}
}
class Cat extends Animal {
public void makeSound() {
System.out.println("Cat is meowing.");
}
}
然后,我们可以创建一个Animal
类型的引用,但实际上它指向的是Dog
类型的对象:
Animal animal = new Dog();
接下来,我们调用makeSound
方法:
animal.makeSound();
由于animal
的实际类型是Dog
,因此会调用Dog
类中重写的makeSound
方法,输出Dog is barking.
运行时多态性是指在运行时根据实际类型确定如何处理对象。具体来说,当我们调用一个方法时,Java虚拟机会根据实际类型动态地确定执行哪段代码。
例如,假设我们有一个Shape
类和它的子类Circle
和Rectangle
:
abstract class Shape {
public abstract double getArea();
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getArea() {
return Math.PI * radius * radius;
}
}
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public double getArea() {
return width * height;
}
}
然后,我们可以创建一个Shape
数组:
Shape[] shapes = new Shape[2];
shapes[0] = new Circle(2.0);
shapes[1] = new Rectangle(3.0, 4.0);
接下来,我们可以遍历数组并调用每个Shape
对象的getArea
方法:
for (Shape shape : shapes) {
System.out.println("Area of " + shape.getClass().getSimpleName() + ": " + shape.getArea());
}
由于Circle
和Rectangle
类都重写了getArea
方法,因此会根据实际类型分别调用这两个方法,输出:
Area of Circle: 12.566370614359172
Area of Rectangle: 12.0
动态方法分派和运行时多态性是Java中的重要特性,它们可以让我们以更加灵活的方式编写代码,同时提高代码的可维护性和可扩展性。在实际编程中,我们应该充分利用这些特性,尽可能使用父类引用来引用子类对象,并根据实际类型动态地调用方法。