那個OOP裡頭class、object、instance間複雜的三角關係

更新於 發佈於 閱讀時間約 14 分鐘
前陣子把《The Nature of Code》這本書大略地看了一遍。這本書在<https://natureofcode.com/>可以免費閱讀,也可以購買紙本或電子書。
這本書的網址放在瀏覽器的書籤中已經有段時間了,但因為書中用來實作的程式語言是Processing p5.js (2024年改版後改用p5.js),而現在正在學的是Python,所以也就一直沒花時間去讀。寫完Stochastic L-system之後,因為還沒決定接下來要寫些什麼,有天百無聊賴地翻著瀏覽器中的書籤,看看有沒有什麼先前收藏,但沒去看的好東西,可以用來打發時間。看到這本書的連結書籤時,想想反正閒著也是閒著,那就看看吧。
這一看不得了,很多想寫的東西的理論觀念和程式寫法,在這本書裡頭都有介紹,而先前寫過的fractal、Game of Life、L-system等,也都包括在其中。既然如此,那就把它看完吧!
這本書用來實作的程式語言是Processing p5.js,不是Python,所以在看的過程中,主要還是著重在理論和觀念部分,程式部分就只是看過去,沒有實際去練習書中的範例和習題。有天看著看著,突然冒出個主意:何不用Python來實作這些範例和習題?這可真是個好主意!這樣既可學到書中介紹的理論、觀念,又可以練習Python。於是決定,把整本書大略看過之後,就從頭再看一遍,邊看邊寫Python程式。另外,還要把心得寫下來,分享到網路上,跟網友互相漏氣求進步。
寫心得的這個決定是對的,就是因為要寫,才發現本來以為自己瞭解的東西,原來並非如此。「教學相長」是個老掉牙的說法,但只要有過認真想「教」好的經驗,絕對會認同這樣的說法,因為除非自己真的完全理解了、學會了,否則是很難教得好的。好的老師,可以讓學生學到東西;厲害的老師,可以讓學生在學習的時候,打從心底浮現「我懂了!我會了!」的豁然開朗笑容;而頂尖的老師,則是會讓學生翻白眼心裡直犯嘀咕:「這麼簡單!我來教都比你教得好!」寫心得與分享,其實就是在教未來的自己與看文章的人,這是檢驗自己是不是真的懂了的最好方法。
心得寫到「Introduction」 「Randomness」這一章的第二節「I.2 0.2 The Random Walker Class」就卡住了,關鍵在這一句話
A class is the template for building actual instances of objects.
這句話是在解釋物件導向程式設計(object-oriented programming, OOP)中的class是什麼。先前看的時候覺的這句話很正常,這就是class的定義,沒啥奇怪的。可是,要寫下心得的時候,卻發現不對勁。印象中,這instance和object不是一樣的東西嗎?怎麼會有「instances of objects」這樣的說法出現?
要寫出來的東西,如果連自己都有疑問,那可不行,非得搞清楚不可,不然寫不下去。
天啊!怎麼這麼混亂!網路上有一卡車的文章在談class、object、instance有什麼不同;在Stack Overflow中,關於object和instance間的差異,也一再有人問起。只是啊只是,看了一大堆的討論、解釋,似乎是懂了,但又總覺得不踏實,就好像漂蕩在太空中,明明目標就在眼前,但無處施力,怎麼也搆不著。
這問題擱在心中好幾天,各種觀點和解釋也不時出沒在腦海中,直到想起書櫃中還有「世紀末軟體革命」這本書。重新再看了一下書中關於這方面的解釋,經過再三的推敲、琢磨,總算踏踏實實地覺得自己懂了。
先來看看查到的資料說些什麼:
  • class是製造object用的藍圖
  • class是描述object細節的藍圖或模板
  • class是用來定義object的一種東西
  • class就是某一類的object,它定義了其內不同object的共通性質
  • object是class的instance,可以把object和instance看作是同樣的東西
  • object是class的複製品,而instance是保有object記憶體位址的變數
  • object是class在記憶體中的physical presence
  • object就是那個使用new來instantiate一個class之後,所產生的那個東西
  • object是一種self-contained entity,具有資料與用來操作該資料的程序
  • instance是特定的object
  • instance是在記憶體中的變數,其內只有存放object的記憶體位址
  • instance就只意味著產生一個reference (copy)
  • instance是object獨一無二,具有相同結構與不同資料的複製品
  • instance就是賦予object的資料,也可稱之為object的狀態
不知各位看倌看了這些說法之後,感覺如何?這些說法單獨來看,似乎都言之成理,可是有些說法之間,卻是互相矛盾的。例如,有些認為object和instance是一樣的東西;有些卻認為先有object,然後再產生instance。怎會這樣呢?
再溫習了一次「世紀末軟體革命」之後,總算能對上述這種混亂的局面理出個頭緒來。原來,這一切都是因為切入點不同所引起的,有些說法是由OOP的理論架構切入;另有些是由程式語言的運作機制切入,而引起混亂的源頭,似乎就是「instance」這個英文字。
想要搞懂class、object、instance這三者間的關係,先從理論架構的視角來看,然後再從實際寫程式時的角度來看,這樣會比較清楚一些。
在現實世界中,人們會把東西分類。例如,那種有四條腿、看到你會搖尾巴、會汪汪叫的東西,人們會把牠們歸為同一類,然後管這類東西叫「狗」。之後當有人說他養了隻叫「開心」的「狗」時,別人雖然沒見過「開心」,但也知道「開心」有四條腿、會對著你搖尾巴、會汪汪叫。以OOP的術語來說,就是人們把有四條腿、看到你會搖尾巴、會汪汪叫的object,歸類為「狗」這個class。這麼一歸類之後,很顯然的,「開心」就是「狗」這個class的一個實際上的例子,也就是instance。
另外還有一種情形,就是人們根據設計圖製作東西。以OOP的角度來看,設計圖就是class,裡頭規範了做出來的東西,也就是object,該是什麼樣子。
上面這兩種過程看起來似乎是相反的,一個是把已存在的object歸入相同的class中;另一個是依據class來製作object。但其實,它們只不過是一個完整過程,掐頭去尾之後的結果。那完整的過程長怎樣呢?完整的過程,就是人們把有四條腿、看到你會搖尾巴、會汪汪叫的object,歸類為「狗」這個class之後,依據「狗」這個class裡頭有的特性,製作出「狗」這個object。
雖然完整的過程是那個樣子,但在OOP裡頭能看到的,就只是其中一部份。當人們使用OOP寫程式時,會先設計class,然後製作object。這個設計class的動作,其實只是看得到的部分,看不到的部分,是腦袋瓜在思考、決定,什麼樣的特性該歸類到這個class裡頭的過程。這個看不到,決定class該長什麼樣子的部分,其實是一切的根基。class設計得不好,就像房子的地基不穩一樣,很難補救的。
從上面的分析,在OOP裡頭,class和object之間的關係就很清楚了。那instance呢?它和class、object間的關係又是怎樣的?
要想搞清楚instance到底是個怎麼樣的存在,就必須搞清楚,到底是class還是object,衍生出instance這麼個讓人混亂的東西來?
看到instance會想到什麼?
蛤?!它不就是個英文字,還能是什麼?
沒錯!instance是個英文字,但這個英文字的意思是什麼?查一下字典,可以知道instance這個字的意思是
  • an example or single occurrence of something
  • a particular case
從instance這個英文字的意思,就可以看得出來,為什麼要用它來描述class和object間的關係,也就是:object是class的instance。而從這樣的關係中,也就能得到「可以把object和instance看作是同樣的東西」這樣子的結論。
既然說object和instance可以看成是一樣的東西,那為什麼又會有「instances of objects」這樣子的說法呢?這樣子不就代表instance是從object生出來,屬於object的嗎?其實這麼說也沒錯,instance這個字,本來就是這個意思。反正一堆東西中的某一個,就是這堆東西的一個instance。之所以會讓人搞不清它是什麼,主要是因為把instance當成了是OOP裡頭,像class、object一樣,有嚴格定義的東西了。所以當看到像「instances of objects」這樣的詞句時,才會疑惑,在談class、object時,不是說instance跟object是同樣的東西嗎,怎麼現在看起來又好像是另一種東西了?
總之,面對一個名詞時,不要先入為主的,就以為是字面上的意思,而應該先搞清楚,人家有沒有事先給了明確的定義。如果沒有明確的定義,就把它當成一般的名詞,根據上下文來理解它的含意。就如同有些書或文件,當談到OOP時,會很明確地說,會把instance和object當成是一樣的東西,而這兩個字也會交替使用。這時候,不用想太多,就把它們當成是一樣的東西來看就可以了。但是啊但是,在有些書中或文件中,並沒有這麼的特別去定義instance是什麼,這時候就必須頭腦清醒地根據上下文來判斷了,Python官網的文件就屬於這種情形。
在Python官網的Glossary文件中,並沒有定義instance是什麼。而在Tutorial的Classes章節中,可以看到像下列這些詞句
  • class instance
  • Many classes like to create objects with instances customized to a specific initial state.
  • instance objects
  • class instance objects
  • instances of that class
這時候,就只能靠上下文來理解instance指的是什麼,而不能一股腦兒的,就把instance和object當成是一樣的東西,否則只會越看越混亂。
在Python中,讓人混亂的不只instance而已,object是另一個狠角色。
在Python中,object這個字,除了原本的翻譯成「物件」的意思之外,所有class的祖先,也是用object這個字。換句話說,object也可能是指那個特定的class。還有啊,因為萬事萬物在Python中,都是「物件」。所以囉,看到class object、instance object、list object、module object、file object、function object、method object等什麼什麼object時,可別太訝異。
接下來,就來看看實際的程式寫法。透過程式,或許會比較能夠理解,前面那一大堆網路上查到的,關於class、object、instance的看法,究竟在說些什麼。
前面提到過「開心」這隻狗,就讓牠來當程式的主角好了。假設我們已經設計好Dog這個class了,接下來,就來看看用Java和Python要怎麼寫,才可以讓「開心」生出來,而且幫牠綁上一條掛有「happy」牌子的狗繩,以免牠走失。
Java的寫法:
Dog happy;
happy = new Dog('開心');
也可以寫成
Dog happy = new Dog('開心');
Python的寫法:
happy = Dog('開心')
當用Dog這個class生出「開心」時,系統會配置記憶體給這個object。至於happy,並非object本身,而是一個指向那個object的reference。從這裡也可以看出,網路上查到的那一大堆解釋,有些有它的道理在,但有些可能就不是那麼的正確了。
過了一年,「開心」長大了,已經一歲了。這時,程式該怎麼寫呢?假設在設計Dog這個class的時候,關於年齡的部分已經考慮進去了,這時候要讓「開心」長大成一歲,Python的寫法是:
happy.age = 1
隨著歲月的流逝,「開心」的年齡也跟著繼續增長,也就是
happy.age = 2
happy.age = 3
...
「開心」還是同一個object,但age不一樣。所以,不同年齡的「開心」,不就是happy這個reference所指的object的instance嗎?既然這樣,那「instances of an object」或「instances of objects」的意思,也就很清楚了。
有陣子常在想,退休之後就來養隻狗、養隻貓,外加一隻老鼠,然後每天就貓抓老鼠狗追貓,這該多麼有趣啊!當然啦,這只能想想,現實生活中是不太可能發生的。現實是,當發現自己又在做著像中大樂透或貓抓老鼠狗追貓這樣子的白日夢時,就知道該舒壓了。不過話又說回來,雖然不能真的在家裡貓抓老鼠狗追貓,那在電腦中模擬總該辦得到吧?
要想在電腦中模擬貓抓老鼠狗追貓,第一步要做的,當然就是要先設計出那三個傢伙。然後……咦?這個「追」是怎麼個追法?是天敵見面分外眼紅,齜牙咧嘴的追,還是吐著舌頭,流著冒著粉紅泡泡口水,眼神充滿對異性愛慕之情的追?
看來又遇上一個複雜的三角關係了……
為什麼會看到廣告
avatar-img
15會員
131內容數
寫點東西自娛娛人
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
你可能也想看
Google News 追蹤
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這篇文章介紹物件導向程式設計(OOP)的基本概念,包括類和物件的定義以及四大核心概念:封裝、繼承、多型和抽象。讀者將瞭解如何在Python中定義類和物件,並學習如何使用這些OOP特性來構建更具組織性和可維護性的程式碼。透過實例,文章探討如何將真實世界的物件模擬到程式設計中。
Thumbnail
這一章節旨在介紹 PHP 中的物件導向編程(OOP)概念。通過詳細講解類別、建構子、訪問修飾符(公開、私有、受保護)、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等概念,使讀者能夠理解和應用這些 OOP 技術來編寫更具結構性和可維護性的 PHP 代碼。
Thumbnail
這篇文章介紹了面試時以及開始工作後可能會遇到的問題,包括物件導向OOP、SOLID 設計原則、測試方式,以及 Cookie、Session 與 Cache 的相似處與不同處。提供了豐富的相關資訊。
Thumbnail
本章節是一個初級的 TypeScript 教學,主要介紹了 TypeScript 中物件導向程式設計的各種核心概念,包括類別、建構子、存取修飾子、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等。每個概念都通過詳細的解釋和實例代碼來進行深入的介紹。
※ class類別 什麼是class? class是創造consturctor function時的語法糖,本質上與使用function創造物件(object)的行為沒有不同。 class的作用: 用來定義、描述要創造的物件(object)具有那些屬性、行為的一個表達式。就像是「車子的設計圖
※ OPP(Object-oriented programming)簡介 什麼是OPP? OPP是一種軟體開發的風格方式。 是一種撰寫程式時的思考模式。 OPP的目的: 企圖將電腦世界的資料類比到現實中「物件」的概念。 將函數化的資料處理方式用類比到現實世界的互動關係,來簡化思考的難度。
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。
Thumbnail
本階段介紹物件導向程式設計(OOP)基礎,從OOP概念、類別與物件基本原理,到PHP中類別與物件的應用,並深入探討封裝、繼承等OOP特性,最後以實際練習加強理解。此階段為學生掌握PHP OOP打下堅實基礎。
Thumbnail
從基本的OOP概念、PHP基礎回顧,到類別與物件的深入探討、進階概念如繼承、介面與抽象類別,再到實戰應用與設計模式入門,最後以課程總結與未來學習資源提供作結。此課程架構確保學生能夠從基礎到進階,全面掌握PHP物件導向程式設計的核心概念與技術。
Thumbnail
本文讓我們來淺談一下類別是什麼? 若想看詳細一點的python官方教學可點此連結 Python 的類別(Class)是一種面向物件導向程式設計的概念,讓你能夠創建具有屬性和方法的物件。類別是對現實世界中事物的抽象,它包含數據和操作這些數據的方法。它非常的抽象,想像一個類別就像是一個蛋糕模具,
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這篇文章介紹物件導向程式設計(OOP)的基本概念,包括類和物件的定義以及四大核心概念:封裝、繼承、多型和抽象。讀者將瞭解如何在Python中定義類和物件,並學習如何使用這些OOP特性來構建更具組織性和可維護性的程式碼。透過實例,文章探討如何將真實世界的物件模擬到程式設計中。
Thumbnail
這一章節旨在介紹 PHP 中的物件導向編程(OOP)概念。通過詳細講解類別、建構子、訪問修飾符(公開、私有、受保護)、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等概念,使讀者能夠理解和應用這些 OOP 技術來編寫更具結構性和可維護性的 PHP 代碼。
Thumbnail
這篇文章介紹了面試時以及開始工作後可能會遇到的問題,包括物件導向OOP、SOLID 設計原則、測試方式,以及 Cookie、Session 與 Cache 的相似處與不同處。提供了豐富的相關資訊。
Thumbnail
本章節是一個初級的 TypeScript 教學,主要介紹了 TypeScript 中物件導向程式設計的各種核心概念,包括類別、建構子、存取修飾子、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等。每個概念都通過詳細的解釋和實例代碼來進行深入的介紹。
※ class類別 什麼是class? class是創造consturctor function時的語法糖,本質上與使用function創造物件(object)的行為沒有不同。 class的作用: 用來定義、描述要創造的物件(object)具有那些屬性、行為的一個表達式。就像是「車子的設計圖
※ OPP(Object-oriented programming)簡介 什麼是OPP? OPP是一種軟體開發的風格方式。 是一種撰寫程式時的思考模式。 OPP的目的: 企圖將電腦世界的資料類比到現實中「物件」的概念。 將函數化的資料處理方式用類比到現實世界的互動關係,來簡化思考的難度。
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。
Thumbnail
本階段介紹物件導向程式設計(OOP)基礎,從OOP概念、類別與物件基本原理,到PHP中類別與物件的應用,並深入探討封裝、繼承等OOP特性,最後以實際練習加強理解。此階段為學生掌握PHP OOP打下堅實基礎。
Thumbnail
從基本的OOP概念、PHP基礎回顧,到類別與物件的深入探討、進階概念如繼承、介面與抽象類別,再到實戰應用與設計模式入門,最後以課程總結與未來學習資源提供作結。此課程架構確保學生能夠從基礎到進階,全面掌握PHP物件導向程式設計的核心概念與技術。
Thumbnail
本文讓我們來淺談一下類別是什麼? 若想看詳細一點的python官方教學可點此連結 Python 的類別(Class)是一種面向物件導向程式設計的概念,讓你能夠創建具有屬性和方法的物件。類別是對現實世界中事物的抽象,它包含數據和操作這些數據的方法。它非常的抽象,想像一個類別就像是一個蛋糕模具,