iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 4
0
Software Development

每天 Racket 3 分鐘系列 第 14

(send day-13 set-title! "Racket 也有物件導向 — Class 與 Object")

  • 分享至 

  • xImage
  •  

1. 這個 OOP 哇哪跨攏謀

今天禮拜天,廢話不多說,我們先上一個範例程式:

(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)

2. Lambda 風味的物件導向

為什麼直接看程式呢?因為我想讓大家先看不懂,再來詳細地討論 Racket 的物件導向。

說到要寫物件導向程式,你會先想到什麼呢?類別?物件?還是 .?如果換個問題好了,我們有一個名叫 racket 的學生,他的基本資料是:

  1. 學號:1
  2. 名字:Racket
  3. 性別:男

他這學期修了三門課:

  1. 資料結構(DataStructures)
  2. 作業系統(OS)
  3. 程式語言理論(PLT)

你會怎麼表示並解決這樣的問題呢?

我們面對複雜世界的複雜問題,最常使用的解法,是分而治之法。在沒有物件導向的語言裡,我們若要表達上述方法,可能會考慮以下流程:

  1. 定義資料型態:student,並且有四項資料屬性:id、name、gender、courses
  2. 定義資料型態:course,並且有一項資料屬性:name
  3. 定義一個名為 racket 的 student 型態
  4. 定義三個課程,分別為上述的名稱
  5. 定義一個名為 join_course 的函式,有兩個參數:student 與 course,做的事情就是把 course 加到 student 的 courses 裡
  6. 執行三次 join_course,分別傳入這三個課程的名稱

在這樣的程式設計觀點裡,我們看待問題,將它分為資料與資料結構,以及演算法與流程,這樣的觀點稱之為演算法分解。然而,在面對更高的複雜度時,雖然我們可以按照資料與它的型態來分辨處理的問題領域,但諸多的函式僅透過參數或回傳值表達了它與哪些資料之間的關係,這樣分解的方式,其實也製造了其他的副作用。

因此,Simula 67 與 SmallTalk 導入了另一種問題的分解方式,稱之為物件導向的問題分解方式,它的概念是這樣的:

  1. 定義一個類別稱為 student,它有四項屬性:id、name、gender、courses,並且三個行為,一個可以取得 name 屬性的內容,一個可以加入課程,一個可以取得 courses 的內容。
  2. 定義一個類別稱為 course,它有一項屬性:name (在此簡化,使用 symbol 代替)
  3. 操作時,建立一個名為 racket 的 student 實體內容與相關的資料
  4. 傳訊息給 racket:get-name,於是 racket 告訴我它的 name
  5. 傳三次訊息給 racket:join-course,參數分別為:'PLT、'OS、'DataStructures,於是 racket 把這些課程加入它的 courses 資料結構中
  6. 傳訊息給 racket: get-current-courses,於是 racket 告訴我它現在已經加入的課程

因此,在物件導向的解法觀點中,程式的操作就是物件之間的互動,演算法不是單純的程式邏輯組成的代碼,而是物件的行為,資料不是單純的數字與文字,而是物件的屬性。

因此,這就是我們上面那段程式碼在操作的內容。

其他的程式細節,容我明天再完整說明。


上一篇
(struct iron-man (day title)) (define today (iron-man 'day-12 "Racket 的資料抽象 — Struct"))
下一篇
(send day-14 set-title! "Racket 也有物件導向 — Class 與 Object — 2")
系列文
每天 Racket 3 分鐘17
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言