Java中的多态性

时间:2020-02-23 14:37:23  来源:igfitidea点击:

多态是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"之间变化。