面向对象编程小结 – A Short Note about OOP

我心飞翔 分类:javascript

一个简短的,面向对象编程 (Object-oriented Programming,简称 OOP) 的笔记

名词解释

对象 Object

  • 对象是一个内部封装了属性和方法的容器。属性是容器的状态,方法是容器的行为或任务。

实例化 Instantiation

  • 通过类 (class) 创建对象实例 (object instance) 的过程,叫做实例化。
  • 对象实例包含数据和类定义的功能。
  • 当对象实例被创建时,它的构造函数会执行然后创建它,也就是说对象实例是从类中实例化出来的。

构造函数 Constructor

  • 在 JavaScript 中,构造函数可以用于创建新的实例对象,让实例对象继承构造函数的属性。
  • JS 不是基于类 (class-based) 的编程语言,但是是基于原型 (prototype-based) 的编程语言。
  • 构造函数的两大特点:
    • 内部的 this 代表即将被创建的对象实例
    • 需要使用 new 操作符来创建新的对象实例

封装 Encapsulation

  • 将相关的数据和方法,打包存储在一个对象中,叫做封装

继承 Inheritance

  • 根据别的类创建新的类,然后新的子类 (child classes, or subclasses)会继承父类 (parent class) 的数据和代码特征,以便之后对相同的功能进行重复利用 (reuse)。
  • 注意这里的继承并非复制 (duplicate)。

多态 Polymorphism

  • 多态是一种接口对多种数据类型的呈现。也可以理解为,多个对象类型实现相同功能的能力
  • 在 OOP 中,每个类都有自己的函数,一旦被任何对象调用,都会有正确的行为功能

对比解释

面向对象编程 VS 面向过程编程

  1. 面向对象编程 Object-oriented Programming

基于对象概念的编程语言,对象包含数据和代码,主要在对象中封装数据和特征,代表语言有 Java,C++,Python 等
2. 面向过程编程 Procedure-oriented Programming
可以理解为基于函数的编程语言,主要解决问题和制定规范;代表语言有 C 语言

继承模式 VS 组合模式

  1. 继承模式 Inheritance Pattern
  • 先定义一个父类,让子类继承父类的属性与方法,严格规定了子类的特征
  • 使用 new 让实例对象都继承父类的属性与方法
  1. 组合模式 Composition Pattern
  • 先定义不同的属性与方法,再组合生成新对象,新对象的特征相对灵活
  • 使用 return Object.assign() ,小括号里选择需要组合的属性与方法

重载 VS 重写

  1. 重载 Overload
  • 同一类中的 2+ 种方法,具有相同的方法名和不同的参数
  1. 重写 Override
  • 2种方法,具有相同的方法名和相同的参数,其中一个方法在父类力,另一个方法在子类力。重写允许子类对父类提供的方法进行特有的执行操作。
  • JS 支持重写 (不支持重载)
  1. 对比
  • 重载是编译时 (compile) 概念,重写是运行时 (run-time) 概念
  • 重写体现了 OOP 的多态性

深拷贝 VS 浅拷贝

  • 浅拷贝:拷贝基本类型数据的方法;也是实现继承的方法,除了使用 prototype 链以外,还可以把父对象的属性,全部拷贝给子对象实现
var Chinese = {nation:'China'}
function extendCopy(p){
  var c = {}
  for (var i in p){
    c[i] = p[i]
  }
  c.uber = p
  return c
}
var Doctor = extendCopy(Chinese)
Doctor.career = 'Doctor'
alert(Doctor.nation) // China
 

这样存在的问题是,如果父对象的属性是一个对象或数组,那么实际上子对象获得的只是一个内存地址,而不是真正的拷贝,存在父对象被篡改的可能性。如果想要让父对象免于被篡改,需要使用深拷贝

  • 深拷贝:实现真正意义上的数组和对象拷贝,在内存中新建一片内存储存数据。思路是递归调用浅拷贝。
function deepCopy(p, c){
  var c = c || {}
  for (var i in p){
    if(typeof p[i] === 'object'){
      c[i] = (p[i].constructor === Array) ? [] : {}
      deepCopy(p[i], c[i])
    } else {
      c[i] = p[i]
    }
  }
  return c
}
 

三大特点与五大原则

特点

封装、继承和多态。

S.O.L.I.D. 原则

SOLID 原则不仅应用于基于对象的设计,而且还是敏捷开发和适应性开发的重要原则。

1. 单一职责 Single Responsibility

每个类都有其唯一的职责,也就是说,这个类只能有一个被改变的理由

2. 开放封闭 Open/Closed

软件应当对拓展持开放态度,对修改持封闭态度

3. 里氏替换 Liskov Substitution

对象应该可以在不改变原程序正确的基础上,对其子类的实例对象进行替换。

4. 接口分离 Interface Segregation

选择使用多个特定的客户端借口 (many client-specific interfaces),而非一个宽泛的综合接口 (general-purpose)

5. 依赖反转 Dependency Inversion

将依赖抽象化,而不要具体化。方法应该遵从“依赖于抽象而不是一个实例”的原则。

参考资料 | Reference List
MDN, Object-oriented JS: developer.mozilla.org/en-US/docs/…
Ruanyifeng's JS Tutorial: wangdoc.com/javascript/…
Wiki SOLID: en.wikipedia.org/wiki/SOLID
zh.wikipedia.org/wiki/%E9%9D…
Stackoverflow, Extract class: stackoverflow.com/questions/3…
Stackoverflow, override VS overload: stackoverflow.com/questions/3…

回复

我来回复
  • 暂无回复内容