@phper
2018-03-13T18:06:20.000000Z
字数 3791
阅读 6674
Golang
原文:https://golangbot.com/inheritance/
欢迎访问Golang 系列教程中的第27章。
go 不支持继承(inheritance), 但是它支持组合(composition)。构图的一般定义是 "放在一起"。组合的一个示例是小轿车。汽车由轮子、引擎和其他各种各样的零件组成。
通过将一个结构类型嵌入到另一个中, 可以在Go中实现组合。
博客文章是作文的完美典范。每个博客帖子都有标题、内容和作者信息。这可以用构图完美地表示出来。在本教程的下一个步骤中, 我们将学习如何完成这项工作。
让我们首先创建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
作为接收器类型, 并返回作者的全名。
下一步是创建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()
方法, 它打印作者的标题、内容、fullName 和bio。
每当一个结构字段嵌入到另一个域中时, 就可以选择访问嵌入字段, 就像它们是外部结构的一部分一样。这意味着上述代码的11行中的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
结构, 让我们通过创建一个博客文章来完成这个程序。
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()
}
在playground上运行
上述程序中的主要功能在31行创建了一个新的作者。通过嵌入author1
, 在36行创建了一个新帖子。此程序打印,
Title: Inheritance in Go
Content: Go supports composition instead of inheritance
Author: Naveen Ramanathan
Bio: Golang Enthusiast
我们可以进一步采取此示例, 并使用博客post
的切片创建网站。
让我们先定义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
}
我已将字段名 post
添加到 []post切片posts
中。
现在, 让我们修改主要功能, 并为我们的新网站创建一些帖子。
修改主功能后的完整程序如下所示,
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()
}
在playground上运行
在上面的主要功能中, 我们创建了一个作者author1和三个帖子post1、 post2和post3。最后, 通过嵌入3个帖子并在下一行中显示内容, 我们创建了62行中的网站w 。
这个程序将输出,
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
这使我们到本教程的末尾。有一个伟大的一天。请留下您的反馈和意见。