面向对象编程

164 阅读3分钟

什么是面向对象编程?

面向对象是一种编程思想,经常被拿来和面向过程比较

1.面向过程编程

面向过程关注的重点是动词,是分析出解决问题需要的步骤,然后编写函数实现每个步骤,最后依次调用编写的函数即可。

2.面向对象编程

面向对象关注的重点是主谓,是把构成问题的事物拆解为各个对象,而拆解出对象的目的也不是为了实现某个步骤,而是为了描述某个事物在当前问题中的各种行为。

面向对象的特点

1.封装

让使用对象的人无需考虑内部实现,只考虑功能的使用,把内部代码保护起来,只留出一些API供外部使用

2.继承

为了代码的复用,从父类上继承出一些方法和属性,子类可以有自己的独立的一些属性

class Father {
    constructor() {
        this.name = "father",
    	this.age = 18
    }
}
Father.prototype.run = function() {
    console.log(this.name + "prototype");
}
class Son extends Father {
    constructor() {
    	super();
    }
}
let person = new Son();
person.run();
console.log(person.name);

3.多态

不同的对象作用于同一操作产生不同的效果。多态的思想实际上是把“想做什么”和“谁去做”分开

比如下棋的过程

面向过程是这样的:开局 -> 白方下棋 -> 棋盘展示 -> 检查胜负 -> 黑方下棋 -> 棋盘展示 -> 检查胜负 -> 循环

用代码表示可能是一连串的函数调用

init();
whitePlay(); // 里面实现一遍下棋的操作
repaint(); // 棋盘展示
check(); // 检查胜负
blackPlay(); // 再单独实现一遍下棋的操作
repaint(); // 棋盘展示
check(); // 检查胜负

面向对象是这样的:棋盘.开局 -> 选手.下棋 -> 棋盘.重新展示 -> 棋盘.检查胜负 -> 选手.下棋 -> 棋盘.重新展示 -> 棋盘.检查胜负

用代码表示可能是这样的

// Checkerboard类内部封装了棋盘的操作,比如初始化棋盘,检查胜负等等
const checkerBoard = new Checkerboard();
//Player类内部封装了各种玩家的操作,比如等待,落棋,悔棋
const whitePlayer = new Player("white");
const blackPlayer = new Player("black");
// start方法的内部封装了(或者通过事件发布触发checkerBoard.repaint(),checkerBoard.check()的调用)
whitePlayer.start();
blackPlayer.start();

你只需要调用new 一个player, 然后调用start方法,也就是说我们只需要关注型维,而不需要知道内部到底做了什么。

而且如果要加一些新功能,比如悔棋,比如再加一个玩家,面向对象都能很好扩展。

在上面的例子中,面向对象的特点是如何体现的呢?

封装:Player,CheckerBoard类,使用的时候并不需要知道内部实现了什么,只需要考虑暴露出来的API的使用

继承:whitePlayer和blackPlayer 都继承自Player,都可以直接使用Player的方法和属性

多态:whitePlayer.start()和blackPlayer.start()下棋的颜色分别是白色和黑色

什么时候适合使用面向对象?

可以看出来,再比较复杂的问题面前,或者参与方较多的时候,面向对象的编程思想可以很好地简化问题,并且能够更好地扩展和维护。

而在比较简单的问题面前,面向对象和面向过程其实差异并不明显。