- 原文地址:Part 27: Composition Instead of Inheritance - OOP in Go
- 原文做者:Naveen R
- 译者:咔叽咔叽 转载请注明出处。
Go 不支持继承,但它支持组合。组合的通用定义是“放在一块儿”。组合的一个例子是汽车。汽车由车轮,发动机和各类其余部件组成。golang
Go 中的组合能够经过将一种结构类型嵌入到另外一种结构类型中来实现。web
博客文章是一个完美的组合示例。每篇博文都有标题,内容和做者信息。这可使用组合完美地表示。在本教程的后续步骤中,咱们将了解如何完成此操做。post
让咱们先建立一个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)
}
复制代码
在上面的代码片断中,咱们建立了一个包含firstName
,lastName
和bio
字段的author
结构。咱们还添加了一个方法fullName()
,author
做为接收者类型,将返回做者的全名。spa
下一步是建立post
结构。code
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()
方法,用于打印做者的title
,content
,fullName
和bio
。继承
每当一个结构嵌入另外一个结构时,Go 为咱们提供了访问嵌入字段的选项,就好像它们是外部结构的一部分同样。这意味着p.author.fullName()
能够用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
结构,让咱们经过建立一个博客帖子来完成这个程序。get
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 行嵌入该做者而后建立一个新帖子。这个程序打印,
Title: Inheritance in Go
Content: Go supports composition instead of inheritance
Author: Naveen Ramanathan
Bio: Golang Enthusiast
复制代码
咱们能够进一步采用这个例子,并使用一些博客帖子建立一个网站:)。
让咱们先定义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 function
并为咱们的新网站建立一些帖子。
修改后的完整程序以下,
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 function
中,咱们建立了一个做者author1
和三个帖子post1
,post2
和post3
。最后咱们在第 62 行建立了网站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
复制代码