Day 02: JavaScript 与 物件导向程序设计

物件导向程序设计是什麽?

英文原文:Object-oriented programming,简称 OOP。

定义

根据英文 Wiki 的定义(连结):

Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code: data in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).

雾煞煞?那中文 Wiki 的定义(连结):

物件导向程序设计是种具有物件概念的程序设计典范,同时也是一种程序开发的抽象方针。它可能包含资料、特性、程序码与方法。物件则指的是类别(class)的实例。它将物件作为程序的基本单元,将程序和资料封装其中,以提高软件的重用性、灵活性和扩充性,物件里的程序可以存取及经常修改物件相关连的资料。在物件导向程序程序设计里,电脑程序会被设计成彼此相关的物件

详细定义可以去 Wiki 看,这边我归纳四点常见特色:

封装性(Encapsulation)

根据英文 Wiki 的定义(连结):

In object-oriented programming (OOP), encapsulation refers to the bundling of data with the methods that operate on that data, or the restricting of direct access to some of an object's components. Encapsulation is used to hide the values or state of a structured data object inside a class, preventing direct access to them by clients in a way that could expose hidden implementation details or violate state invariance maintained by the methods.

中文 Wiki 定义(连结):

一种将抽象性函式介面的实作细节部份包装、隐藏起来的方法。同时,它也是一种防止外界呼叫端,去存取物件内部实作细节的手段,这个手段是由程序语言本身来提供的。

简单来说,就是资料能不能被隐藏起来。

继承(Inheritance)

根据英文 Wiki 的定义(连结):

In object-oriented programming, inheritance is the mechanism of basing an object or class upon another object (prototype-based inheritance) or class (class-based inheritance), retaining similar implementation. Also defined as deriving new classes (sub classes) from existing ones such as super class or base class and then forming them into a hierarchy of classes. In most class-based object-oriented languages, an object created through inheritance, a "child object", acquires all the properties and behaviors of the "parent object" , with the exception of: constructors, destructor, overloaded operators and friend functions of the base class. Inheritance allows programmers to create classes that are built upon existing classes, to specify a new implementation while maintaining the same behaviors (realizing an interface), to reuse code and to independently extend original software via public classes and interfaces. The relationships of objects or classes through inheritance give rise to a directed graph.

中文 Wiki 定义(连结

使得子类具有父类别别的各种属性和方法,而不需要再次编写相同的代码。在令子类别继承父类别别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别别的原有属性和方法,使其获得与父类别别不同的功能。另外,为子类追加新的属性和方法也是常见的做法。

简单来说,透过继承让物件之间产生关联,在开发上可以减少重复撰写相同程序码。

多型(Polymorphism)

根据英文 Wiki 的定义(连结):

In programming languages and type theory, polymorphism is the provision of a single interface to entities of different types or the use of a single symbol to represent multiple different types.

中文 Wiki 定义(连结

为不同资料类型的实体提供统一的介面,或使用一个单一的符号来表示多个不同的类型。

简单来说,就是不同物件使用相同名称的方法,方法的细节可以不同。

抽象性(Abstraction)

根据英文 Wiki 的定义(连结):

In software engineering and computer science, abstraction is:

  • the process of removing physical, spatial, or temporal details or attributes in the study of objects or systems to focus attention on details of greater importance; it is similar in nature to the process of generalization;
  • the creation of abstract concept-objects by mirroring common features or attributes of various non-abstract objects or systems of study[3] – the result of the process of abstraction.

中文 Wiki 定义(连结

将资料与程序,以它的语意来呈现出它的外观,但是隐藏起它的实作细节。

简单来说,将复杂的事物以简化的内容描述,方便後续的实作。

题外话,本身是化学系毕业,对於 abstract 的记忆是分析化学的 萃取,两者的中文意思不同,概念上却一致,取出精华的部分。一想到这点的我,不禁对於程序语言采用 abstract 感到赞叹。

到底 JavaScript 能不能算是符合物件导向程序设计的语言?

这个问题很有趣,如果搜寻关键字:「is javascript a object oriented language」,会有不少正反方的讨论,有时间大家可以去了解双方的看法。

众多看法中,这位前辈的论述最得我心(连结),藉由多型、封装性、继承来讨论,这边引用原文:

  • 多型
    • Pretty much all dynamic languages do that

  • 封装性
    • Pretty easy to do in Javascript also

  • 继承
    • Tip the balance as to whether a language qualifies to be called object oriented.

    • Javascript does provide a fairly easy means to inherit implementation via prototyping but this is at the expense of encapsulation.

Javascript 的继承不是传统认知的实作方式,而是采用 Prototype-chain 继承模式。两者的差异是:

  • 传统上,一旦两个 Class 有继承关系,那子代可以取得亲代所有的属性与方法。当子代使用来自於亲代的属性与方法时,是使用自身的。
  • Prototype-chain 则不是这回事,一旦两个 Class 有继承关系,子代不会拥有亲代的属性与方法,当使用者呼叫亲代的属性或方法时,子代会藉由 __proto__ 找到亲代後询问有没有对应的方法与属性,如果有则使用者呼叫成功,没有的话,继续往上一层亲代找寻,直到找到对应的,或是告知呼叫错误错误。

所以说 JavaScript 不是物件导向程序设计的语言罗?

精准定义上,不能算是,但在使用上,基於万物都是物件这点,JavaScript 可以算是物件导向程序设计的语言,只是不能完全运用来自於拥有良好继承性语言的经验,必须使用不同的手段避开因为缺少的部分而产生的问题。

可能的问题是:

  • 缺乏 Interface。
  • 缺乏 Abstract Class。
  • 缺乏 Access Modifier(Public、Private、Protected)。

这些是未来撰写上的挑战,也是 JavaScript 使用 Design Patterns 要克服的坎。

补充:常见的物件导向程序设计的语言

使用率较高的语言清单,参考 StackOverflow 2021 Developer Survey,仅列出常见的网页开发、手机、平板语言。

而物件导向程序设计的语言清单来自英文 Wiki(连结)。

语言 是物件导向程序设计的语言吗
JavaScript YES
Python YES
Java YES
TypeScript YES
C# YES
PHP YES, since v4, greatly enhanced in v5
Go YES
Kotlin YES
Rust YES
Ruby YES
Swift YES

没错,全部都是物件导向程序设计的语言,令人惊讶但不意外的结果,物件导向程序设计的良好特性促使程序开发蓬勃发展。


<<:  Day 12 运算宝石:【Lab】EC2储存资源 EBS Volume 建立与使用 (上)

>>:  [Day 02] 什麽是tinyML?

Vue slot: 具名插槽

tags: Vuejs 具名插槽 ✐ 若是需要多个插槽,可以在 <slot> 中使用 n...

Angular Stock登入(二)(Day22)

今天我们要实作如何利用Angular内提供的模组,从form表单取值。 FormModel: Bot...

沟通这回事:ORID 与引导

前言 昨天分享了冰山理论,今天接着谈「焦点讨论法 | ORID」,并在後半延伸至引导学(Facili...

[Day 13] 整体学习 (Ensemble Learning)

整体学习 (Ensemble Learning) 今日学习目标 了解整体学习 何谓整体学习? 三种不...

JS Library 学习笔记:Three.js 初见面,在2D画面创造三维世界 (四)

在真实世界中,物体因为反射光进我们的眼中,而能被看见;因此,除了物体形状外,材质与光之间的关系是3D...