# 面向对象编程

创建时间:2019-02-21

# 提普斯

突然被问到,对 JavaScript 的面对对象编程是怎么理解的?

然后一道面试题(记忆),创建一个父类 Animal,拥有属性:type,age,和方法:say,walk。子类 Dog 继承父类 Animal ,并增加属性 name 和 color,重写父类的方法 say 。

# 定义

面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针。它可能包含数据、属性、代码与方法。对象则指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关连的数据。在面向对象程序编程里,计算机程序会被设计成彼此相关的对象

引自维基百科 (opens new window)

面对对象顾名思义就是把所有的事物都抽象成为"对象"。就像这道面试题 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
1
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
1
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
1
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
1
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~
1
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~
1
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的实现方法。对封装,继承,多态,又理解了一遍。

# 参考

上次更新: 4/27/2020, 5:06:39 PM