- Go 教程系列筆記 Interface 第一部分
- Go 教程系列筆記 Interface 第二部分
- Go 教程系列筆記 併發介紹
- Go 教程系列筆記 goroutine(協程)
- Go 教程系列筆記 Channel 通道
- Go 教程系列筆記 緩衝通道和工作池
- Go 教程系列筆記 Select
- Go 教程系列筆記 Mutex(互斥鎖)
- Go 教程系列筆記 結構而不是類-Go中的OOP
- Go 教程系列筆記 組合而不是繼承-Go 中的 OOP
- Go 教程系列筆記 多態-Go 中的 OOP
Go不支持繼承,但它確實支持組合。組合的通用定義是“放在一起”。組合的一個例子是汽車。汽車由車輪,發動機和各種其他部件組成。
通過嵌入結構組成
Go中的組合可以通過將一種結構類型嵌入到另一種結構類型中來實現。
博客文章是一個完美的組合示例。每篇博文都有標題,內容和作者信息。這可以使用組合完美地表示。在本教程的後續步驟中,我們將瞭解如何完成此操作。
<!-- more -->
讓我們首先創建author
結構。
package main
import (
"fmt"
)
type author struct {
firstName string
lastName string
bio string
}
func (a author) fullName() string {
return fmt.Sprintf("%s %s", a.firstName, a.lastName)
}
在上面的代碼片段中,我們創建了一個author帶字段的結構,firstName,lastName和bio。我們還添加了一個fullName()
帶有author
接收器類型的方法,它返回作者的全名。
下一步是創建post
結構。
type post struct {
title string
content string
author
}
func (p post) details() {
fmt.Println("Title: ", p.title)
fmt.Println("Content: ", p.content)
fmt.Println("Author: ", p.author.fullName())
fmt.Println("Bio: ", p.author.bio)
}
post
結構有字段 title,content。它還有一個嵌入式匿名字段author
。該字段表示post
結構由author
組成。現在post
結構可以訪問author
結構的所有字段和方法。我們還在post
結構中添加了details()方法,用於打印作者的標題,內容,完整名稱和生物。
每當一個struct字段嵌入另一個struct時,Go爲我們提供了訪問嵌入字段的選項,就好像它們是外部結構的一部分一樣。這意味着p.author.fullName()
在行中沒有。上面的代碼第 10 行中可以替換爲p.fullName()
。因此,該details()方法可以重寫如下,
func (p post) details() {
fmt.Println("Title: ", p.title)
fmt.Println("Content: ", p.content)
fmt.Println("Author: ", p.fullName())
fmt.Println("Bio: ", p.bio)
}
現在我們已經準備好author和post結構,讓我們通過創建一個博客文章來完成這個程序。
package main
import (
"fmt"
)
type author struct {
firstName string
lastName string
bio string
}
func (a author) fullName() string {
return fmt.Sprintf("%s %s", a.firstName, a.lastName)
}
type post struct {
title string
content string
author
}
func (p post) details() {
fmt.Println("Title: ", p.title)
fmt.Println("Content: ", p.content)
fmt.Println("Author: ", p.fullName())
fmt.Println("Bio: ", p.bio)
}
func main() {
author1 := author{
"Naveen",
"Ramanathan",
"Golang Enthusiast",
}
post1 := post{
"Inheritance in Go",
"Go supports composition instead of inheritance",
author1,
}
post1.details()
}
上面程序中的主要功能是在第31行號中創建一個新作者。在第36行創建一個新文章。並嵌入式author
。這個程序打印。
Title: Inheritance in Go
Content: Go supports composition instead of inheritance
Author: Naveen Ramanathan
Bio: Golang Enthusiast
嵌入 slice 結構
我們可以把這個例子進一步修改,創建使用一個網站有一系列博客文章:)。
讓我們先定義website
結構。請在現有程序的主要功能上方添加以下代碼並運行它。
type website struct {
[]post
}
func (w website) contents() {
fmt.Println("Contents of Website\n")
for _, v := range w.posts {
v.details()
fmt.Println()
}
}
在添加上面的代碼後運行上面的程序時,編譯器會抱怨以下錯誤,
main.go:31:9: syntax error: unexpected [, expecting field name or embedded type
此錯誤指向嵌入的結構切片[]post
。原因是不可能匿名嵌入切片。字段名稱是必需的。所以讓我們修復這個錯誤並使編譯器滿意。
type website struct {
posts []post
}
我已將字段名稱posts
添加到 []post。
現在讓我們修改main.go
併爲我們的新網站創建一些帖子。
修改主要功能後的完整程序如下所示,
package main
import (
"fmt"
)
type author struct {
firstName string
lastName string
bio string
}
func (a author) fullName() string {
return fmt.Sprintf("%s %s", a.firstName, a.lastName)
}
type post struct {
title string
content string
author
}
func (p post) details() {
fmt.Println("Title: ", p.title)
fmt.Println("Content: ", p.content)
fmt.Println("Author: ", p.fullName())
fmt.Println("Bio: ", p.bio)
}
type website struct {
posts []post
}
func (w website) contents() {
fmt.Println("Contents of Website\n")
for _, v := range w.posts {
v.details()
fmt.Println()
}
}
func main() {
author1 := author{
"Naveen",
"Ramanathan",
"Golang Enthusiast",
}
post1 := post{
"Inheritance in Go",
"Go supports composition instead of inheritance",
author1,
}
post2 := post{
"Struct instead of Classes in Go",
"Go does not support classes but methods can be added to structs",
author1,
}
post3 := post{
"Concurrency",
"Go is a concurrent language and not a parallel one",
author1,
}
w := website{
posts: []post{post1, post2, post3},
}
w.contents()
}
在上面的main.go
中,我們創建了一個作者author1
和三個帖子post1,post2並且post3。最後我們在第63行創建了網站 w。通過嵌入這3個帖子並在下一行顯示內容。
該程序將輸出,
Contents of Website
Title: Inheritance in Go
Content: Go supports composition instead of inheritance
Author: Naveen Ramanathan
Bio: Golang Enthusiast
Title: Struct instead of Classes in Go
Content: Go does not support classes but methods can be added to structs
Author: Naveen Ramanathan
Bio: Golang Enthusiast
Title: Concurrency
Content: Go is a concurrent language and not a parallel one
Author: Naveen Ramanathan
Bio: Golang Enthusiast