# 面向对象编程
创建时间:2019-02-21
# 提普斯
突然被问到,对 JavaScript 的面对对象编程是怎么理解的?
然后一道面试题(记忆),创建一个父类 Animal,拥有属性:type,age,和方法:say,walk。子类 Dog 继承父类 Animal ,并增加属性 name 和 color,重写父类的方法 say 。
# 定义
面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针。它可能包含数据、属性、代码与方法。对象则指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关连的数据。在面向对象程序编程里,计算机程序会被设计成彼此相关的对象
面对对象顾名思义就是把所有的事物都抽象成为"对象"。就像这道面试题 Animal 和 Dog 都是可以抽象为对象,下面根据对象的特点,一步步实现面试题。
# 特点
# 封装
具备封装性(Encapsulation)的面向对象程序设计隐藏了某一方法的具体执行步骤,取而代之的是通过消息传递机制传送消息给它。例子:Animal 有 say() 方法,这个方法定义了 Animal 通过身份方法 say ,但是对外界来说并不知道它内部是如何运作的。
// ES6
class Animal {
constructor(type, age) {
this.type = type
this.age = age
}
say() {
console.log(`${this.type} say something`)
}
...
}
let animal = new Animal('dog', 2)
animal.say() // dog say something
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// ES5
function Animal(type, age) {
this.type = type
this.age = age
}
Animal.prototype.say = function () {
console.log(`${this.type} say something`)
}
var animal = new Animal('dog', 2)
animal.say() // dog say something
2
3
4
5
6
7
8
9
10
11
12
# 继承
继承性(Inheritance)是指,在某种情况下,一个类会有“子类”。子类会继承父类的属性方法这些成员。例子:新创建一个 Dog 继承 Animal,Dog 类就会继承 Animal 类的属性:type,age,和方法:say,walk。
// ES6
class Dog extend Animal{
constructor(type, age, color){
super(type, age)
this.color = color
}
say(){
super.say() // 调用父类的方法
console.log(`${this.color} ${this.type} say something`) // 定义 Dog 的相关操作
}
walk(){
console.log(`${this.color} ${this.type} walking`) // 定义 Dog 的新方法
}
}
console.log(Animal.isPrototypeOf(Dog)) // true
let tugou = new Dog('tugou', 2, 'yellow')
console.log(Dog.prototype.isPrototypeOf(tugou)) // true
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ES5
function Dog (type, age, color){
// 继承属性
Animal.call(this, type, age)
this.color = color
}
// 继承方法
Dog.prototype = new Animal()
// 修改构造函数的指向
Dog.prototype.constructor = Animal
// 重写 Dog 的 say 方法
Dog.prototype.say = function(){
console.log(`${this.color} ${this.type} say something`) // 定义 Dog 的相关操作
}
// 添加 Dog 的 walk 方法
Dog.prototype.walk = function(){
console.log(`${this.color} ${this.type} walking`) // 定义 Dog 的新方法
}
var tugou = new Dog('tugou', 2, 'yellow')
tugou.say() // yellow tugou say something
tugou.walk() // yellow tugou walking
Dog.say() // Uncaught TypeError: Dog.say is not a function
Dog.prototype.say() // undefined undefined say something
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 多态
多态(Polymorphism)是指由继承而产生的相关的不同的类,其对象对同一消息会做出不同的响应。例如,Dog 和 Cat 都继承自 Animal ,都有 say 方法,但是可以进行重写使 say 方法有不同的操作。
class Dog extends Animal{
constructor(type, age, color){
super(type, age)
this.color = color
}
say(){
console.log(`${this.color} ${this.type} wang! wang! wang!`) // 定义 Dog 的相关操作
}
}
class Cat extends Animal{
constructor(type, age, color){
super(type, age)
this.color = color
}
say(){
console.log(`${this.color} ${this.type} miao~ miao~ miao~`) // 定义 Cat 的相关操作
}
}
let tugou = new Dog('tugou', 2, 'yellow')
let lanmao = new Cat('lanmao', 2, 'gray')
tugou.say() // yellow tugou wang! wang! wang!
lanmao.say() // gray lanmao miao~ miao~ miao~
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function Dog (type, age, color){
// 继承属性
Animal.call(this, type, age)
this.color = color
}
// 继承方法
Dog.prototype = new Animal()
// 修改构造函数的指向
Dog.prototype.constructor = Animal
// 重写 Dog 的 say 方法
Dog.prototype.say = function(){
console.log(`${this.color} ${this.type} wang! wang! wang!`) // 定义 Dog 的相关操作
}
function Cat (type, age, color){
// 继承属性
Animal.call(this, type, age)
this.color = color
}
// 继承方法
Cat.prototype = new Animal()
// 修改构造函数的指向
Cat.prototype.constructor = Animal
// 重写 Cat 的 say 方法
Cat.prototype.say = function(){
console.log(`${this.color} ${this.type} miao~ miao~ miao~`) // 定义 Cat 的相关操作
}
var tugou = new Dog('tugou', 2, 'yellow')
var lanmao = new Cat('lanmao', 2, 'gray')
tugou.say() // yellow tugou wang! wang! wang!
lanmao.say() // gray lanmao miao~ miao~ miao~
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
至此,就算整理了一遍js创建对象的ES5/ES6的实现方法。对封装,继承,多态,又理解了一遍。
# 参考
← 前端文件下载 Vue - 手动挂载组件 →