JavaScript 中的多态性

Mehvish Ashiq 2023年1月30日 2022年5月10日
  1. 什么是 JavaScript 中的多态性
  2. 在 JavaScript 中为什么使用多态性
  3. JavaScript 中的多态性如何工作
JavaScript 中的多态性

本教程围绕 JavaScript 中的多态性展开。

在本课中,我们将学习什么是多态性。为什么使用它?它是如何工作的,我们如何在 JavaScript 中实现它?

什么是 JavaScript 中的多态性

多态是面向对象编程(OOP)的核心概念之一。在进入细节之前了解多态的字面含义是很好的。

Poly 一词的意思是许多多个morph 的意思是形式。因此,多态性意味着多种形式多种形式

继承允许我们将父类的属性(属性和方法)继承到子类中。多态性通过覆盖执行各种任务来获得这些方法的优势。

它进一步分为两类:

  1. 静态多态
  2. 动态多态

静态多态发生在编译时,也称为编译时多态。与方法重载相同。

由于 JavaScript 不是编译语言,它本身不支持静态多态。但我们可以通过使用替代品来模仿它。

另一方面,动态多态发生在运行时(程序执行期间),也称为运行时多态。JavaScript 是解释型语言,使得方法覆盖可以实现动态多态性。

我们将在标题为 JavaScript 中的多态性工作的第三部分中看到这两个示例。

在 JavaScript 中为什么使用多态性

由于以下优点而使用多态性。

  1. 我们可以重用已经编写和测试过的代码。
  2. 由于使用了多态,代码很容易调试。
  3. 节省时间,提高工作质量。

JavaScript 中的多态性如何工作

本节将学习静态和动态多态在 JavaScript 中的工作原理。

JavaScript 中的静态多态是如何工作的

静态多态性与函数重载相同(我们可以拥有多个名称完全相同但参数不同的方法),但这在 JavaScript 中不受支持,因为由于名称相同,JavaScript 会用最新的方法覆盖旧方法。

但是有一种方法可以模拟静态多态性。请参阅下面给出的示例代码。

class calculator{
 	constructor(){}
 	sum(num1, num2, num3){
 		if(num3 != undefined){
 			console.log("Sum is called with three parameters");
 			return num1+num2+num3;
    	}else{
 			console.log("Sum is called with two parameters");
 			return num1+num2;
    	}
  	}
}

const c = new calculator();
console.log(c.sum(2,3));
console.log(c.sum(2,3,4));

输出:

"Sum is called with two parameters"
5
"Sum is called with three parameters"
9

我们在上面给出的代码中使用 if-else 条件来模拟静态多态性。我们调用 sum() 方法两次。我们在第一次调用时传递两个参数,在第二次调用时传递三个参数。

检查类 calculator 是否第三个参数是 undefined。如果是,则为两个参数执行 sum();否则,对于三个参数。

假设我们为四个参数调用 sum() 方法。现在,代码如下所示。

class calculator{
	constructor(){}
 	sum(num1, num2, num3, num4){
 		if(num4 != undefined){
 			console.log("Sum is called with four parameters");
 			return num1+num2+num3+num4;
    	}else if(num3 != undefined){
 			console.log("Sum is called with three parameters");
 			return num1+num2+num3;
    	}else{
 			console.log("Sum is called with two parameters");
 			return num1+num2;
    	}
  	}
}

const c = new calculator();
console.log(c.sum(2,3));
console.log(c.sum(2,3,4));
console.log(c.sum(2,3,4,5));

输出:

"Sum is called with two parameters"
5
"Sum is called with three parameters"
9
"Sum is called with four parameters"
14

在 JavaScript 中动态多态性如何工作

动态多态性允许我们以多种方式执行单个操作。例如,我们有一个函数 calculateArea(),我们可以在子类中重写它来计算圆和矩形的面积。

继承是动态多态的前提。让我们通过下面的例子来理解。

形状类:

class Shape{
	calculateArea(){
 		console.log("shape.calculateArea is called.");
 		return 0;
  }
}

矩形类:

class Rectangle extends Shape{
 	constructor(length, width){
		super();
 		this.length = length;
 		this.width = width;
	}
	calculateArea(){
 		console.log("rectangle.calculateArea is called.");
 		return this.length * this.width;
	}
}

类:

class Circle extends Shape{
 	constructor(radius){
 		super();
 		this.radius = radius;
	}
	calculateArea(){
 		console.log("circle.calculateArea is called.");
 		return Math.PI * this.radius ** 2;
	}
}

主要代码:

s = new Rectangle(3,4);
console.log(s.calculateArea());
s= new Circle(2);
console.log(s.calculateArea());

输出:

"rectangle.calculateArea is called."
12
"circle.calculateArea is called."
12.566370614359172

请注意,我们在父类(即 Shape)和子类(RectangleCircle)中具有相同的 calculateArea() 方法,但它们的工作方式不同。这是因为持有不同对象的引用。

s 在此代码中包含 Rectangle 类的引用 s = new Rectangle(3,4); 但它在代码 s= new Circle(2); 中包含 Circle 类的引用。

我们如何知道变量 s 持有哪个引用?它是在运行时决定的,因为对象是在运行时创建的;这就是为什么它被称为动态多态性。

另一个问题是如何找出方法 calculateArea() 是从哪个类调用的,因为它存在于父类和所有子类中。

同样,它取决于在运行时创建的对象。假设 s 持有 Circle 类的对象,而 Circle 已覆盖 calculateArea() 方法。

在这种情况下,将调用 Circle 类中的 calculateArea()

假设 Circle 没有覆盖 calculateArea() 方法;在这种情况下,calculateArea() 方法将从 Circle 的父级调用,即 Shape

练习时,从 Circle 类中删除 calculateArea() 并运行代码;你将看到以下输出。

"rectangle.calculateArea is called."
12
"shape.calculateArea is called."
0

你是否注意到从 Shape 类调用 calculateArea()?这是因为 Circle 类没有覆盖它。

Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook