TypeScript 中的鴨子型別
什麼是鴨子型別?
首先,我們將瞭解什麼是鴨子型別。根據程式設計師的說法,物件型別由其行為(例如方法和屬性)而不是其類來決定的情況稱為“鴨子型別”。
TypeScript 中的鴨子型別
TypeScript 中介面的使用使得鴨子型別成為可能。其中介面意味著描述了物件必須具有的方法和特性集才能屬於該型別。
例如,如果一個介面定義了函式,則任何具有名為“myFunc()”的方法的物件都可以被視為屬於特定型別,而不管其類如何。當兩個物件共享相同行為並且可以互換使用時,可以實現更大的程式碼靈活性。
鴨子型別強調透過考慮物件的方法和屬性來評估物件是否適合執行任務,而不是考慮其實際型別。介面解釋了物件必須具有的屬性和方法集,才能被視為特定目的的“鴨子型別”。
鴨子型別的優勢
鴨子型別的主要優勢之一是使程式碼更加靈活和可重用。程式碼適用於任何具有所需方法和屬性的物件,而不是僅適用於特定型別的物件,並且可以在各種情況下使用而無需修改。鴨子型別還透過允許在單個程式碼庫中互換使用不同型別的物件來提高程式碼重用性。
TypeScript 中鴨子型別的示例
以下是如何在 TypeScript 中使用鴨子型別的示例:
定義一個表示您希望物件具有的行為的介面。例如:
interface Duck { quack(): void; }
建立一個實現該介面的類。例如:
class MallardDuck implements Duck { quack(): void { console.log("Quack!"); } }
建立該類的例項並將其用作介面定義的型別。
let duck: Duck = new MallardDuck(); duck.quack(); // Output: "Quack!"
建立另一個也實現該介面的類:
class RubberDuck implements Duck { quack(): void { console.log("Squeak!"); } }
使用新類例項作為介面定義的相同型別。
let duck: Duck = new RubberDuck(); duck.quack(); // Output: "Squeak!"
如您所見,MallardDuck 和 RubberDuck 類都實現了 Duck 介面,並且 duck 變數可以分配給這兩個類的例項。型別由介面中定義的行為(方法和屬性)而不是類來確定。
還需要注意的是,在 TypeScript 中,可以使用 typeof 關鍵字在執行時檢查物件的型別,以及物件是否具有預期的方法或屬性。
示例
在此示例中,Bird 和 Plane 類實現了 Flyable 介面,該介面需要 fly() 方法。這兩個“鴨子型別”可以在 goFly() 函式中互換使用。該函式不關心傳遞給它的物件的實際型別,只要它具有可以呼叫的 fly() 方法即可。
interface Flyable { fly(): void; } class Bird implements Flyable { fly(): void { console.log("Bird is flying"); } } class Plane implements Flyable { fly(): void { console.log("Plane is flying"); } } function goFly(flyable: Flyable) { flyable.fly(); } let bird = new Bird(); let plane = new Plane(); goFly(bird); // Prints "Bird is flying" goFly(plane); // Prints "Plane is flying"
編譯後,它將生成以下 JavaScript 程式碼:
var Bird = /** @class */ (function () { function Bird() { } Bird.prototype.fly = function () { console.log("Bird is flying"); }; return Bird; }()); var Plane = /** @class */ (function () { function Plane() { } Plane.prototype.fly = function () { console.log("Plane is flying"); }; return Plane; }()); function goFly(flyable) { flyable.fly(); } var bird = new Bird(); var plane = new Plane(); goFly(bird); // Prints "Bird is flying" goFly(plane); // Prints "Plane is flying"
輸出
以上程式碼將產生以下輸出:
Bird is flying Plane is flying
示例
總的來說,鴨子型別是一種強大的程式設計概念,它允許透過允許不同型別的物件互換使用(只要它們具有相同的方法和屬性)來提高 TypeScript 程式碼的靈活性和可重用性。在此示例中,Driveable 介面、Car 和 Truck 類顯示了相同的內容。
interface Driveable { drive(): void; } class Car implements Driveable { drive(): void { console.log("Car is driving"); } } class Truck implements Driveable { drive(): void { console.log("Truck is driving"); } } function goDrive(driveable: Driveable) { driveable.drive(); } let car = new Car(); let truck = new Truck(); goDrive(car); // Prints "Car is driving" goDrive(truck); // Prints "Truck is driving"
編譯後,它將生成以下 JavaScript 程式碼:
var Car = /** @class */ (function () { function Car() { } Car.prototype.drive = function () { console.log("Car is driving"); }; return Car; }()); var Truck = /** @class */ (function () { function Truck() { } Truck.prototype.drive = function () { console.log("Truck is driving"); }; return Truck; }()); function goDrive(driveable) { driveable.drive(); } var car = new Car(); var truck = new Truck(); goDrive(car); // Prints "Car is driving" goDrive(truck); // Prints "Truck is driving"
輸出
以上程式碼將產生以下輸出:
Car is driving Truck is driving
鴨子型別背後的主要思想是,程式碼應該編寫為適用於任何具有其所需方法和屬性的物件,而不是編寫為適用於特定物件。這可以使程式碼更靈活、更可重用,使您能夠互換使用不同型別的物件而無需更改程式碼。