這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
golang中並沒有明確的物件導向的說法,實在要扯上的話,可以將struct比作其它語言中的class。
類聲明
type Poem struct {
Title string
Author string
intro string
}
這樣就聲明了一個類,其中沒有public、protected、private的的聲明。golang用另外一種做法來實現屬性的存取權限:屬性的開頭字母是大寫的則在其它包中可以被訪問,否則只能在本包中訪問。類的聲明和方法亦是如此。
類方法聲明
func (poem *Poem) publish() {
fmt.Println("poem publish")
}
或者
func (poem Poem) publish() {
fmt.Println("poem publish")
}
和其它語言不一樣,golang聲明方法和普通方法一致,只是在func後增加了poem *Poem這樣的聲明。加*和沒有加*的區別在於一個是傳遞指標對象,一個是傳遞值對象。
執行個體化對象
執行個體化對象有好幾種方式
poem := &Poem{}
poem.Author = "Heine"
poem2 := &Poem{Author: "Heine"}
poem3 := new(Poem)
poem3.Author = "Heine"
poem4 := Poem{}
poem4.Author = "Heine"
poem5 := Poem{Author: "Heine"}
執行個體化的時候可以初始化屬性值,如果沒有指明則預設為系統預設值
加&符號和new的是指標對象,沒有的則是值對象,這點和php、java不一致,在傳遞對象的時候要根據實際情況來決定是要傳遞指標還是值。
tips:當對象比較小的時候傳遞指標並不划算。
建構函式(自己創造)
func NewPoem(param string, p ...interface{}) *Poem
樣本:
func NewPoem(author string) (poem *Poem) {
poem = &Poem{}
poem.Author = author
return
}
poem6 := NewPoem("Heine")
繼承
確切的說golang中叫做組合(composition)
type Poem struct {
Title string
Author string
intro string
}
type ProsePoem struct {
Poem
Author string
}
ProsePoem屬性中聲明了Poem,表示組合了Poem的屬性和方法。可以像如下方式調用:
prosePoem := &ProsePoem{}
prosePoem.author = "Heine"
如果其中屬性有衝突,則以外圍的為主。
type ProsePoem struct {
Poem
Author string
}
當訪問Author的時候預設為ProsePoem的Author,如果需要訪問Poem的Author屬性可以使用prosePoem.Poem.Author來訪問。
prosePoem := &ProsePoem{}
prosePoem.Author = "Shelley"
prosePoem.Poem.Author = "Heine"
fmt.Println(prosePoem)
從輸出中可以很直觀看到這一點。
&{{ Heine } Shelley}
方法的繼承和屬性一致,這裡不再羅列。通過組合的話可以很好的實現多繼承。
方法重載
方法重載就是一個類中可以有相同的函數名稱,但是它們的參數是不一致的,在java、C++中這種做法普遍存在。golang中如果嘗試這麼做會報重新聲明(redeclared)錯誤,但是golang的函數可以聲明不定參數,這個非常強大。
func (poem *Poem) recite(v ...interface{}) {
fmt.Println(v)
}
其中v …interface{}表示參數不定的意思,其中v是slice類型,fmt.Println方法也是這樣定義的。如果要根據不同的參數實現不同的功能,要在方法內檢測傳遞的參數。