多态是指同一个接口或父类引用变量可以指向不同的对象实例,并根据实际指向的对象类型执行相应的方法。
它允许同一个方法在不同的对象上表现出不同的行为,是面向对象编程(OOP)的核心特性之一。
多态的优点:
- 通过多态,程序可以灵活地处理不同类型的对象,降低代码耦合度,增强系统的可扩展性。新增子类或实现类时,无需修改原有代码,只需通过接口或父类引用调用即可。
扩展知识
多态的意义(理解)
多态其实是一种抽象行为,它的主要作用是让程序员可以面对抽象编程而不是具体的实现类,这样写出来的代码扩展性会更强。
大家可能不是很理解什么是抽象什么是具体,我举个可能不是很恰当但是很好理解的例子:比如某个人很喜欢吃苹果,我们在写文章描述他的时候可以写他很喜欢吃苹果,也可以写他很喜欢吃水果。
水果就是抽象,苹果就是具体的实现类。
假设这个人某天开始换口味了,他喜欢吃桃子了,如果我们之前的文章写的是水果,那么完全不需要改,如果写的是苹果,是不是需要把苹果替换成桃子了?
这就是多态的意义。
再举个代码的例子:
比如 Person person = new Student ()
Person 是父类,含有一个工作的方法,student 重写工作的方法,比如上学。
class Person {void work() {System.out.println("工作");}
}class Student extends Person {@Overridevoid work() {System.out.println("上学");}
}public class Test {public static void main(String[] args) {Person person = new Student();person.work(); // 输出 "上学"}
}
这样在使用的时候,对象都是 person ,但是 new 不同的实现类,表现的形式不同,这也就从字面上解释的什么叫多态。
编译时多态和运行时多态
编译时多态和运行时多态是面向对象编程中多态性的两种实现方式,它们分别在不同的阶段决定方法的绑定。
- 编译时多态:通过方法重载实现,在编译时确定方法的调用。
- 运行时多态:通过方法重写实现,在运行时确定方法的调用。
1.编译时多态(Compile-time Polymorphism )
编译时多态,也称为静态多态,是在编译阶段确定方法的调用。编译时多态主要通过方法重载(Method Overloading )实现。
方法重载:指在同一个类中定义多个方法,这些方法的名称相同但参数列表(参数的类型或数量)不同。Java 编译器在编译时会根据方法调用时传入的参数类型和数量,决定调用哪一个重载方法。
示例:
class Example {void display(int a) {System.out.println("Integer: " + a);}void display(double a) {System.out.println("Double: " + a);}void display(String a) {System.out.println("String: " + a);}
}public class Main {public static void main(String[] args) {Example obj = new Example();obj.display(5); // 调用 display(int a)obj.display(3.14); // 调用 display(double a)obj.display("Hello"); // 调用 display(String a)}
}
在这个例子中,根据传入的参数类型,编译器在编译时决定调用哪个 display 方法。
2.运行时多态(Runtime Polymorphism )
运行时多态,也称为动态多态,是在运行时确定方法的调用,运行时多态通过方法重写(Method Overriding )实现。
方法重写:子类重写父类的一个或多个方法。通过父类引用调用方法时,实际执行的是子类重写后的方法。这种多态性是在运行是根据对象的实际类型决定的。
示例:
class Animal {void sound() {System.out.println("Animal makes a sound");}
}class Dog extends Animal {@Overridevoid sound() {System.out.println("Dog barks");}
}class Cat extends Animal {@Overridevoid sound() {System.out.println("Cat meows");}
}public class Main {public static void main(String[] args) {Animal myDog = new Dog(); // Animal reference but Dog objectAnimal myCat = new Cat(); // Animal reference but Cat objectmyDog.sound(); // 输出: Dog barksmyCat.sound(); // 输出: Cat meows}
}