多态是一种面向对象编程的概念,它允许我们使用统一的接口来操作不同类型的对象。这意味着,尽管多个对象具有不同的内部结构和实现,但它们可以共享相同的行为或方法。在Java中,多态性主要体现在方法重载(overloading)和方法覆盖(overriding)上。
方法重载是指在同一个类中定义多个同名方法,但这些方法的参数列表必须不同(参数数量或类型不同),编译器会根据调用时提供的参数来选择合适的方法。这是一种编译时多态,因为它在编译期间就决定了调用哪个方法。
方法覆盖则是指子类重新定义父类中的方法,子类提供了与父类相同的方法名称和参数列表,但可能有不同的实现。这通常是通过运行时多态实现的,因为方法的具体调用是在运行时根据对象的实际类型决定的。
多态的好处包括:
1.灵活性:可以编写更加通用的代码,不依赖于具体的类实现。
2.可扩展性:可以在不影响现有代码的情况下添加新的子类。
例子:
假设有一个 S 类,它有一个 draw() 方法,然后有 Circle 和 Rectangle 两个子类分别继承 Shape 并覆盖了 draw() 方法:
class S {
void draw() {
System.out.println("画");
}
}
class C extends S {
@Override
void draw() {
System.out.println("圆");
}
}
class R extends S {
@Override
void draw() {
System.out.println("矩形");
}
}
现在,如果我们有一个 S 类型的数组,它可以包含 C和 R 对象,并且我们可以通过遍历数组调用每个对象的 draw() 方法,而不需要关心具体是什么类型的形状:
public class Main {
public static void main(String[] args) {
Shape[] shapes = new Shape[2];
shapes[0] = new C();
shapes[1] = new R();
for (int i = 0; i < shapes.length; i++) {
shapes[i].draw(); // 运行时会根据实际对象类型调用相应的方法
}
}
}
在这个例子中,无论是 C 还是 R对象,都可以被当作 S对象来处理,这就是多态性的体现。每次循环时,draw() 方法的调用将取决于当前对象的实际类型,即运行时多态。