iT邦幫忙

2021 iThome 鐵人賽

DAY 2
0
Software Development

也該是時候學學 Design Pattern 了系列 第 2

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 01: 緣由、大綱
下一篇
Day 03: 面對 Design Pattern 該有的知識
系列文
也該是時候學學 Design Pattern 了31

1 則留言

0
TD
iT邦新手 5 級 ‧ 2021-09-17 10:04:24

就我的理解,「物件導向程式語言」代表能夠支援或實現「物件導向程式設計」的程式語言,而其實「物件導向程式設計」有許多特徵和行為,所以只要能夠實現部分特徵和行為的程式語言我想都可以被稱作「物件導向程式語言」 :)

我要留言

立即登入留言