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