Inheritance
昨天學完怎麼在結構上加方法後,它就很像在設計物件導向程式了。今天來看看它怎麼實作繼承。
昨天學完怎麼在結構上加方法後,它就很像在設計物件導向程式了。今天來看看它怎麼實作繼承。
今天開始,我們要一起來面對骯髒的程式碼了。
昨天了解 Carbon 套件是利用繼承來擴充物件的行為,我們今天一起來看看它是怎麼設計的。
首先原始碼註解很明確的分很多實作區塊,如 GETTERS AND SETTERS,接下來會以這些區塊來說明它擴充的方法。
這個區塊的方法都是在建立物件,所以大部分都是靜態方法。
分為幾種類型:
Carbon::instance())Carbon::parse())來取代 newCarbon::now())Carbon::today())、昨天(Carbon::yesterday())、明天(Carbon::tomorrow())。Carbon::maxValue())與最小值(Carbon::minValue())Carbon::create())與經過把關的建立方法(Carbon::createSafe())Carbon::createFrom*())Carbon::copy())以下會挑幾個特別的方法做說明:
instance()這個方法會先判斷是不是自己(Carbon)的實例,再決定要如何做事。
如果是的話會使用 clone,不過事實上改成使用 copy() 這樣也是可行的:
結構可以定義同類型的資料,而同類型的資料通常又會有同類型的行為。因為 Go 有 Anonymous Function,有寫過 Javascript 可能第一個想到的解法是這樣:
Carbon 本身並不複雜,它使用兩個物件,分別繼承了原生 PHP [DateTime][] 與 [DateInterval][] 類別,並實作了新的行為,讓它更好使用。
以下會翻 Carbon 1.22.1 版來說做明。
在學 Design Pattern 時,常會聽到要「多用組合,少用繼承」。繼承這麼可怕,怎麼至今大多數語言都支援呢?這表示,繼承雖然有風險,但能避開風險的話,它仍然是個好用的觀念。像 Carbon 就是一個很好的例子,使用繼承擴展功能後,反而受到大多數開發者的喜愛。
我們這幾天可以一起來看看 Carbon 怎麼安全地實作繼承。
物件導向設計原則中,其中有一個原則是--里氏替換原則,身為一個子類,如果要繼承家業的話,必須要把父類原本做的事做好才行,就算有想要改善或是調整,也不能破壞行為。
所以,首先我們來看 Carbon 類別繼承了 [DateTime][] 哪些實作,來了解它是改善調整,還是破壞行為。
使用 IDE 可以很清楚知道下面這些方法有做覆寫:
原文:
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend on details. Details should depend on abstractions.
struct 是定義資料的集合,跟物件很像,也是把資料集合在一包。
昨天在使用 callback 的時候,有用到匿名函式。今天來看一下匿名函式的其他細節。