JavaScript - 繼承

你好,未來的 JavaScript 巫師們!今天,我們將踏上一段令人興奮的旅程,探索 JavaScript 中的神奇世界——繼承。別擔心你對編程還是新手;我將成為你的友好指南,我們將一步步探索這個概念。所以,拿起你的虛擬魔杖(鍵盤),讓我們一起深入!

JavaScript - Inheritance

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 摩托車上表演輪胎離地!

CarMotorcycle 都從 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 中的繼承提供了多種優勢:

  1. 代碼重用性
  2. 擴展性
  3. 可維護性
  4. 多態性

以下是一個總結這些優勢的表格:

優勢 描述
代碼重用性 從父類別繼承屬性和方法,減少重複
擴展性 易於為現有類別添加新功能
可維護性 父類別的更改自動反映在子類別中
多態性 通過相同的接口使用不同類別的對象

記住,力量越大,責任越大。明智地使用繼承,你的代碼會感謝你!

那就是了,各位!我們一起穿越了 JavaScript 繼承的土地。我希望這個指南為你照亮了道路。持續練習,保持好奇心,並且快樂編程!

Credits: Image by storyset