JavaScript - 繼承
你好,未來的 JavaScript 巫師們!今天,我們將踏上一段令人興奮的旅程,探索 JavaScript 中的神奇世界——繼承。別擔心你對編程還是新手;我將成為你的友好指南,我們將一步步探索這個概念。所以,拿起你的虛擬魔杖(鍵盤),讓我們一起深入!
JavaScript 中的繼承
繼承就像是將家族特徵傳遞下來,但在編程的世界中。想像你正在創建一個對象的家譜,其中子對象可以從父母那裡繼承屬性和方法。酷炫吧?
讓我們從一個簡單的例子開始:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} 發出聲音。`);
}
}
class Dog extends Animal {
bark() {
console.log(`${this.name} 吠叫:汪汪!`);
}
}
const myDog = new Dog("Buddy");
myDog.speak(); // 輸出:Buddy 發出聲音。
myDog.bark(); // 輸出:Buddy 吠叫:汪汪!
在這個例子中,Dog
繼承自 Animal
。這意味著 Dog
獲得了 Animal
的所有屬性和方法,加上它自己獨特的方法 bark()
。這就像 Buddy 繼承了所有動物的說話能力,但還有他特殊的吠叫超能力!
JavaScript 的單一類別繼承
單一類別繼承是指一個類別只從一個父類別繼承。這就像是有個超級酷炫的父親,你想要學習他的一切。
這裡有另一個例子:
class Vehicle {
constructor(brand) {
this.brand = brand;
}
start() {
console.log(`啟動 ${this.brand}。`);
}
}
class Car extends Vehicle {
honk() {
console.log(`${this.brand} 車發出嘟嘟聲!`);
}
}
const myCar = new Car("Toyota");
myCar.start(); // 輸出:啟動 Toyota。
myCar.honk(); // 輸出:Toyota 車發出嘟嘟聲!
在這裡,Car
繼承自 Vehicle
。這就像你的車從車輛的一般概念中學會了如何啟動,但也知道如何嘟嘟聲,因為,嗯,它是車!
JavaScript 的 super() 鍵字
現在,讓我們來聊聊 super()
鍵字。它就像是一個對父母尊敬的點頭,認同他們對你超凡魅力的貢獻。
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 呼叫父類別的構造函數
this.breed = breed;
}
introduce() {
console.log(`我是 ${this.name},一隻 ${this.breed} 狗。`);
}
}
const myDog = new Dog("Max", "Labrador");
myDog.introduce(); // 輸出:我是 Max,一隻 Labrador 狗。
在 Dog
構造函數中的 super(name)
呼叫就像是在說:"嘿,動物父母,你能幫我設置名字嗎?" 這是一種重用父類別構造函數邏輯的方式。
JavaScript 的多級繼承
多級繼承就像是一個有著多代的家譜。讓我們看一個例子:
class Animal {
constructor(name) {
this.name = name;
}
eat() {
console.log(`${this.name} 正在吃東西。`);
}
}
class Dog extends Animal {
bark() {
console.log(`${this.name} 說汪汪!`);
}
}
class Labrador extends Dog {
swim() {
console.log(`${this.name} 正在游泳。`);
}
}
const myDog = new Labrador("Charlie");
myDog.eat(); // 輸出:Charlie 正在吃東西。
myDog.bark(); // 輸出:Charlie 說汪汪!
myDog.swim(); // 輸出:Charlie 正在游泳。
在這裡,Labrador
繼承自 Dog
,而 Dog
又繼承自 Animal
。這就像 Charlie the Labrador 從所有動物那裡學會了吃東西,從狗那裡學會了吠叫,並且有他自己特殊的游泳能力。
JavaScript 的層次繼承
層次繼承是當多個類別從單一父類別繼承時。這就像兄弟姐妹從同一個父母那裡繼承特徵。
class Vehicle {
constructor(brand) {
this.brand = brand;
}
start() {
console.log(`啟動 ${this.brand}。`);
}
}
class Car extends Vehicle {
drive() {
console.log(`駕駛 ${this.brand} 車。`);
}
}
class Motorcycle extends Vehicle {
wheelie() {
console.log(`在 ${this.brand} 摩托車上表演輪胎離地!`);
}
}
const myCar = new Car("Toyota");
const myBike = new Motorcycle("Harley");
myCar.start(); // 輸出:啟動 Toyota。
myCar.drive(); // 輸出:駕駛 Toyota 車。
myBike.start(); // 輸出:啟動 Harley。
myBike.wheelie(); // 輸出:在 Harley 摩托車上表演輪胎離地!
Car
和 Motorcycle
都從 Vehicle
繼承,但他們各有自己獨特的方法。
繼承類別的靜態成員
靜態成員屬於類別本身,而不是實例。但它們還是可以被繼承的!我們來看看如何:
class MathOperations {
static PI = 3.14159;
static calculateCircleArea(radius) {
return this.PI * radius * radius;
}
}
class AdvancedMath extends MathOperations {
static calculateSphereVolume(radius) {
return (4/3) * this.PI * radius * radius * radius;
}
}
console.log(AdvancedMath.PI); // 輸出:3.14159
console.log(AdvancedMath.calculateCircleArea(5)); // 輸出:78.53975
console.log(AdvancedMath.calculateSphereVolume(3)); // 輸出:113.09733
在這裡,AdvancedMath
繼承了 MathOperations
的靜態 PI
屬性和 calculateCircleArea
方法。
JavaScript 的原型繼承
在 ES6 類別之前,JavaScript 使用原型繼承。這有點複雜,但理解它仍然很重要:
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} 發出聲音。`);
};
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
console.log(`${this.name} 吠叫:汪汪!`);
};
const myDog = new Dog("Rex");
myDog.speak(); // 輸出:Rex 發出聲音。
myDog.bark(); // 輸出:Rex 吠叫:汪汪!
這實現了與我們第一個類別範例相同的结果,但使用的是较老的原型語法。
繼承的優勢
JavaScript 中的繼承提供了多種優勢:
- 代碼重用性
- 擴展性
- 可維護性
- 多態性
以下是一個總結這些優勢的表格:
優勢 | 描述 |
---|---|
代碼重用性 | 從父類別繼承屬性和方法,減少重複 |
擴展性 | 易於為現有類別添加新功能 |
可維護性 | 父類別的更改自動反映在子類別中 |
多態性 | 通過相同的接口使用不同類別的對象 |
記住,力量越大,責任越大。明智地使用繼承,你的代碼會感謝你!
那就是了,各位!我們一起穿越了 JavaScript 繼承的土地。我希望這個指南為你照亮了道路。持續練習,保持好奇心,並且快樂編程!
Credits: Image by storyset