什么是面向对象编程?
面向对象是一种编程思想,经常被拿来和面向过程比较
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()下棋的颜色分别是白色和黑色
什么时候适合使用面向对象?
可以看出来,再比较复杂的问题面前,或者参与方较多的时候,面向对象的编程思想可以很好地简化问题,并且能够更好地扩展和维护。
而在比较简单的问题面前,面向对象和面向过程其实差异并不明显。