今天禮拜天,廢話不多說,我們先上一個範例程式:
(define student%
(class object%
(init id name gender)
(define student-id id)
(define student-name name)
(define student-gender gender)
(define courses '())
(super-new)
(define/public get-name
(lambda ()
student-name))
(define/public join-course
(lambda (course)
(set! courses (cons course courses))))
(define/public get-current-courses
(lambda ()
courses))))
(define racket (new student% [id 1]
[name "Racket"]
[gender 'M]))
(send racket get-name)
(send racket join-course 'PLT)
(send racket join-course 'OS)
(send racket join-course 'DataStructures)
(send racket get-current-courses)
執行之後,會得到以下結果:
"Racket"
'(DataStructures OS PLT)
為什麼直接看程式呢?因為我想讓大家先看不懂,再來詳細地討論 Racket 的物件導向。
說到要寫物件導向程式,你會先想到什麼呢?類別?物件?還是 .
?如果換個問題好了,我們有一個名叫 racket
的學生,他的基本資料是:
他這學期修了三門課:
你會怎麼表示並解決這樣的問題呢?
我們面對複雜世界的複雜問題,最常使用的解法,是分而治之法。在沒有物件導向的語言裡,我們若要表達上述方法,可能會考慮以下流程:
在這樣的程式設計觀點裡,我們看待問題,將它分為資料與資料結構,以及演算法與流程,這樣的觀點稱之為演算法分解。然而,在面對更高的複雜度時,雖然我們可以按照資料與它的型態來分辨處理的問題領域,但諸多的函式僅透過參數或回傳值表達了它與哪些資料之間的關係,這樣分解的方式,其實也製造了其他的副作用。
因此,Simula 67 與 SmallTalk 導入了另一種問題的分解方式,稱之為物件導向的問題分解方式,它的概念是這樣的:
因此,在物件導向的解法觀點中,程式的操作就是物件之間的互動,演算法不是單純的程式邏輯組成的代碼,而是物件的行為,資料不是單純的數字與文字,而是物件的屬性。
因此,這就是我們上面那段程式碼在操作的內容。
其他的程式細節,容我明天再完整說明。