Java编译时多态和运行时多态
在面向对象编程中,多态是一个重要的概念。它允许我们以统一的方式处理不同类型的对象,并在运行时根据对象的实际类型调用相应的方法。在Java中,多态有两种形式:编译时多态和运行时多态。本文将详细介绍这两种多态形式的概念以及如何使用它们。
编译时多态
在编译时多态中,方法的调用是在编译时确定的,即根据引用变量的类型来决定调用哪个方法。这种多态是通过方法重载实现的。方法重载是指在同一个类中定义多个同名的方法,但它们的参数列表不同。编译器根据参数的数量和类型来选择调用哪个方法。
让我们看一个简单的例子来理解编译时多态:
public class PolymorphismExample {
public static void main(String[] args) {
Shape shape = new Shape();
shape.draw();
Circle circle = new Circle();
circle.draw();
Rectangle rectangle = new Rectangle();
rectangle.draw();
}
}
class Shape {
public void draw() {
System.out.println("Drawing a shape");
}
}
class Circle extends Shape {
public void draw() {
System.out.println("Drawing a circle");
}
}
class Rectangle extends Shape {
public void draw() {
System.out.println("Drawing a rectangle");
}
}
在上面的代码中,我们定义了一个Shape
类和两个子类Circle
和Rectangle
。Shape
类有一个draw
方法,Circle
和Rectangle
类分别重写了draw
方法。
在main
方法中,我们创建了一个Shape
对象,并调用了它的draw
方法。由于shape
变量的类型是Shape
,编译器会在编译时确定调用Shape
类的draw
方法。
接下来,我们创建了一个Circle
对象,并调用了它的draw
方法。同样,由于circle
变量的类型是Circle
,编译器会在编译时确定调用Circle
类的draw
方法。
最后,我们创建了一个Rectangle
对象,并调用了它的draw
方法。同样,由于rectangle
变量的类型是Rectangle
,编译器会在编译时确定调用Rectangle
类的draw
方法。
在以上所有情况中,编译器根据变量的类型来确定调用哪个方法。这就是编译时多态。
运行时多态
在运行时多态中,方法的调用是在运行时确定的,即根据对象的实际类型来决定调用哪个方法。这种多态是通过方法重写实现的。方法重写是指在子类中定义一个与父类中具有相同名称和参数列表的方法。当子类对象调用这个方法时,将执行子类中的方法而不是父类中的方法。
让我们看一个简单的例子来理解运行时多态:
public class PolymorphismExample {
public static void main(String[] args) {
Shape shape = new Circle();
shape.draw();
shape = new Rectangle();
shape.draw();
}
}
class Shape {
public void draw() {
System.out.println("Drawing a shape");
}
}
class Circle extends Shape {
public void draw() {
System.out.println("Drawing a circle");
}
}
class Rectangle extends Shape {
public void draw() {
System.out.println("Drawing a rectangle");
}
}
在上面的代码中,我们创建了一个Shape
对象,并将它赋值给一个shape
变量。然后,我们调用了shape
的draw
方法。由于shape
变量的实际类型是Circle
,所以运行时会调用Circle
类的draw
方法。
接下来,我们将一个Rectangle
对象赋值给shape
变量,并再次调用了shape
的draw
方法。由于shape
变量的实际类型是Rectangle
,所以运行时会调用Rectangle
类的draw
方法。
在以上所有情况中,方法的调用是在运行时确定的,根据对象的实