Java中的多态性
多态是OOPS范式的核心概念之一。
多态性的含义是以几种不同形式出现的条件。
1.什么是多态性?
多态是在不同场景下执行不同任务的能力。
有时,多态性基于函数的输入参数。
在继承的情况下也可以存在多态性。
这些函数的行为根据实际实现而有所不同。
2.多态现实生活中的例子
一个人的功能之一就是写作。
如果给该人铅笔和纸,那么他将在上面写一些字。
如果向该人展示油漆和着色书,他将作画。
在此,函数根据输入参数的行为有所不同。送货人员将物品运送到给定的地址。
如果是邮递员,他会把信件和软件包寄到家里。
如果是披萨送货员,他会把披萨送货给您。
其中传递函数的多态性是通过不同的实现方式实现的。
3. Java中的多态
Java支持多态,它可以分为两种类型。
- 编译时多态
- 运行时多态
4.编译时多态
当编译器能够确定实际功能时,称为编译时多态性。
有两种类型的编译时多态性。
- 方法重载
- 运算符重载
4.1)方法重载
当一个类中的不同函数具有相同的名称但签名不同时,则称为方法重载。
方法签名包含名称和方法参数。
因此,重载方法具有不同的参数。
参数的数量或者类型可能有所不同。
方法的返回类型不是签名的一部分。
这是Java中方法重载的简单示例。
import java.io.File; class Printer{ void print(String message) { //printing string message } void print(String message, int count) { //printing message count times } boolean print(Object obj, File f) { //printing object to file return true; } }
如果要在JDK类中查找方法重载,则可以在String和原始包装器类中找到很多方法重载。
例如,String valueOf()方法,Integer parseInt()方法等。
Java字符串类中的方法重载
4.2)运算符重载
Java不允许我们覆盖运算符。
但是,对于String对象,加法(+)运算符已重载。
当加法运算符与字符串对象一起使用时,它将它们连接起来并返回一个新的字符串对象。
jshell> 10 + 5 ==> 15 jshell> 10.5 + 20.1 ==> 30.6 jshell> "ABC" + "abc" ==> "ABCabc" jshell> new Object() + new Object() | Error: | bad operand types for binary operator '+' | first type: java.lang.Object | second type: java.lang.Object | new Object() + new Object() | ^-------------------------^ jshell>
推荐阅读:Java中的字符串连接
5.运行时多态
运行时多态性通过方法重写来实现。
当超类方法在子类中被覆盖时,称为方法覆盖。
在这种情况下,编译器无法确定将调用超类还是子类方法。
方法解析在运行时根据对象的实际类型发生。
这就是为什么将其称为运行时多态性。
也称为动态方法调度。
这是Java中运行时多态的示例。
package com.theitroad.examples; import java.util.Random; public class DeliveryBoy { void deliver() { System.out.println("Delivering Item"); } public static void main(String[] args) { DeliveryBoy db = getDeliveryBoy(); db.deliver(); } private static DeliveryBoy getDeliveryBoy() { Random rand = new Random(); int num = rand.nextInt(10); return num % 2 == 0 ? new PizzaDeliveryBoy() : new Postman(); } } class PizzaDeliveryBoy extends DeliveryBoy { @Override void deliver() { System.out.println("Delivering Pizza"); } } class Postman extends DeliveryBoy { @Override void deliver() { System.out.println("Delivering Letters"); } }
PizzaDeliveryBoy和Postman类中的deliver()
方法已被覆盖。
编译器无法确定getDeliveryBoy()将返回PizzaDeliveryBoy还是Postman。
因此,方法解析在运行时发生。
如果运行该程序,输出将在" Delivering Letters"和" Delivering Pizza"之间变化。