JavaScript - 多态

你好,未来的JavaScript法师们!今天,我们将踏上一段激动人心的旅程,探索JavaScript中的多态世界。别担心,这个词听起来可能很吓人——但到了这节课结束时,你将能够像专业人士一样运用多态性!

JavaScript - Polymorphism

JavaScript中的多态

让我们从基础开始。多态是一个来自希腊语的时髦词,意思是“多种形式”。在编程中,它指的是对象能够采取多种形式或行为的能力。把它想象成变色龙改变颜色以适应不同的环境。

在JavaScript中,多态允许我们使用单个接口来表示不同类型的对象。这就像拥有一个万能遥控器,可以操作各种设备——你的电视、DVD播放器和音响系统——都可以用同样的按钮。

下面是一个简单的例子来说明这个概念:

function makeSound(animal) {
console.log(animal.sound());
}

let dog = {
sound: function() {
return "汪汪!";
}
};

let cat = {
sound: function() {
return "喵喵!";
}
};

makeSound(dog); // 输出: 汪汪!
makeSound(cat); // 输出: 喵喵!

在这个例子中,我们有一个makeSound函数,它可以处理不同的动物对象。dogcat都有一个sound方法,但它们产生不同的输出。这就是多态性的实际运用!

方法重写

多态性的一个关键方面是方法重写。当子类为在父类中已经定义的方法提供一个具体的实现时,就会发生这种情况。

让我们来看一个例子:

class Animal {
makeSound() {
return "动物发出声音";
}
}

class Dog extends Animal {
makeSound() {
return "狗吠";
}
}

class Cat extends Animal {
makeSound() {
return "猫叫";
}
}

let animal = new Animal();
let dog = new Dog();
let cat = new Cat();

console.log(animal.makeSound()); // 输出: 动物发出声音
console.log(dog.makeSound());    // 输出: 狗吠
console.log(cat.makeSound());    // 输出: 猫叫

在这里,我们有一个带有makeSound方法的Animal类。DogCat类扩展了Animal并重写了makeSound方法,用自己的实现。这允许每种动物都有自己的独特声音,同时仍然是Animal家族的一部分。

示例

让我们通过更多的例子来深入理解JavaScript中的多态性。

示例 1:形状计算器

想象我们在构建一个形状计算器。我们想要使用相同的方法名称来计算不同形状的面积。

class Shape {
calculateArea() {
return 0;
}
}

class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}

calculateArea() {
return Math.PI * this.radius * this.radius;
}
}

class Rectangle extends Shape {
constructor(width, height) {
super();
this.width = width;
this.height = height;
}

calculateArea() {
return this.width * this.height;
}
}

function printArea(shape) {
console.log("面积是: " + shape.calculateArea());
}

let circle = new Circle(5);
let rectangle = new Rectangle(4, 6);

printArea(circle);    // 输出: 面积是: 78.53981633974483
printArea(rectangle); // 输出: 面积是: 24

在这个例子中,我们有一个基类Shape和两个派生类CircleRectangle。每个类都实现了自己的calculateArea方法。printArea函数可以处理任何形状对象,展示了多态性。

示例 2:员工薪资系统

让我们创建一个简单的员工薪资系统来进一步说明多态性:

class Employee {
constructor(name, salary) {
this.name = name;
this.salary = salary;
}

calculateBonus() {
return this.salary * 0.1;
}
}

class Manager extends Employee {
calculateBonus() {
return this.salary * 0.2;
}
}

class Developer extends Employee {
calculateBonus() {
return this.salary * 0.15;
}
}

function printBonus(employee) {
console.log(`${employee.name}的奖金是: $${employee.calculateBonus()}`);
}

let john = new Employee("John", 50000);
let jane = new Manager("Jane", 70000);
let bob = new Developer("Bob", 60000);

printBonus(john); // 输出: John的奖金是: $5000
printBonus(jane); // 输出: Jane的奖金是: $14000
printBonus(bob);  // 输出: Bob的奖金是: $9000

在这个例子中,我们有不同类型的员工,他们的奖金计算规则不同。printBonus函数可以处理任何员工对象,展示了多态性。

使用JavaScript中多态性的好处

现在我们已经看到了多态性的实际应用,让我们谈谈为什么它如此出色:

  1. 代码可重用性:多态性允许我们编写更通用和可重用的代码。我们的printAreaprintBonus函数可以分别处理任何形状或员工对象。

  2. 灵活性:添加新类型的对象时更容易,无需更改现有代码。我们可以添加一个Triangle类到我们的形状计算器中,而不需要修改printArea函数。

  3. 可维护性:多态性可以导致更干净、更有组织的代码,更容易维护和扩展。

  4. 抽象:它允许我们在更高的抽象层次上处理对象,关注对象做什么而不是如何做。

下面是一个总结我们在示例中使用的关键方法的表格:

方法 描述
calculateArea() 计算形状的面积
calculateBonus() 计算员工的奖金
makeSound() 返回动物发出的声音
sound() 返回动物发出的声音(在对象字面量示例中)

记住,年轻的学者们,多态性就像是你编程工具箱中的瑞士军刀。它多功能、强大,并能让你编写更优雅、高效的代码。继续练习,很快你就能用多态性通往JavaScript的掌握之路!

Credits: Image by storyset