封装、继承、多态
封装、继承和多态是面向对象编程(OOP)的三大基本特性。这些概念在 JavaScript 中也有相应的实现方式,尽管 JavaScript 的面向对象机制与传统的类基语言(如 Java 或 C++)有所不同。下面详细介绍这三大特性在 JavaScript 中的应用。
1. 封装 (Encapsulation)
定义:封装是指将数据(属性)和操作数据的方法绑定在一起,形成一个独立的单元(即对象),并且尽可能隐藏对象内部的实现细节,只暴露必要的接口给外部使用。
目的:
- 提高模块化程度。
- 保护数据不被外部直接访问或修改。
- 降低代码之间的耦合度。
JavaScript 实现:
- 使用构造函数和闭包来实现封装。
- 使用
private变量和方法(通过立即执行函数表达式 IIFE)。
示例:
javascript
function Person(name) {
let _name = name; // 私有变量
function getName() {
// 私有方法
return _name;
}
function setName(newName) {
// 私有方法
_name = newName;
}
this.getName = function () {
// 公共方法
return getName();
};
this.setName = function (newName) {
// 公共方法
setName(newName);
};
}
const alice = new Person("Alice");
console.log(alice.getName()); // 输出: Alice
alice.setName("Alicia");
console.log(alice.getName()); // 输出: Alicia2. 继承 (Inheritance)
定义:继承是指一个对象(子类)可以继承另一个对象(父类)的属性和方法,从而实现代码重用和扩展。
目的:
- 代码重用。
- 扩展功能而不改变现有代码。
JavaScript 实现:
- 原型链继承。
- 构造函数继承。
- 组合继承。
- 寄生组合继承。
- ES6 类的继承。
示例(使用 ES6 类的继承):
javascript
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, I'm ${this.name}`);
}
}
class Student extends Person {
constructor(name, grade) {
super(name); // 调用父类构造函数
this.grade = grade;
}
study() {
console.log(`I'm studying in grade ${this.grade}`);
}
}
const alice = new Student("Alice", 10);
alice.greet(); // 输出: Hello, I'm Alice
alice.study(); // 输出: I'm studying in grade 103. 多态 (Polymorphism)
定义:多态是指同一个接口可以有不同的实现方式。在运行时,根据对象的实际类型来决定调用哪个方法。
目的:
- 提高代码的灵活性和可扩展性。
- 使代码更加通用和易于维护。
JavaScript 实现:
- 通过方法重写(覆盖)实现多态。
- 通过鸭子类型(Duck Typing)实现多态。
示例(方法重写):
javascript
class Animal {
speak() {
console.log("Some generic animal sound");
}
}
class Dog extends Animal {
speak() {
console.log("Woof woof!");
}
}
class Cat extends Animal {
speak() {
console.log("Meow meow!");
}
}
function makeSound(animal) {
animal.speak();
}
const dog = new Dog();
const cat = new Cat();
makeSound(dog); // 输出: Woof woof!
makeSound(cat); // 输出: Meow meow!示例(鸭子类型):
javascript
function makeSound(animal) {
if (animal && typeof animal.speak === "function") {
animal.speak();
} else {
console.log("This is not an animal!");
}
}
const dog = {
speak: function () {
console.log("Woof woof!");
},
};
const cat = {
speak: function () {
console.log("Meow meow!");
},
};
const nonAnimal = {};
makeSound(dog); // 输出: Woof woof!
makeSound(cat); // 输出: Meow meow!
makeSound(nonAnimal); // 输出: This is not an animal!总结
- 封装:通过构造函数和闭包实现,隐藏内部实现细节,只暴露必要的接口。
- 继承:通过原型链、构造函数、组合继承、寄生组合继承以及 ES6 类的继承实现。
- 多态:通过方法重写和鸭子类型实现,提高代码的灵活性和可扩展性。
理解并正确使用这些面向对象的基本特性,可以帮助你编写出更清晰、更灵活且易于维护的 JavaScript 代码。如果你有更多关于封装、继承和多态的具体问题或需要进一步的例子,请告诉我!