分享
  1. 首页
  2. 文章

[译] part 27: golang 的面向对象 -- 组合取代继承

咔叽咔叽_7647 · · 1680 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Go 不支持继承,但它支持组合。组合的通用定义是"放在一起"。组合的一个例子是汽车。汽车由车轮,发动机和各种其他部件组成。

通过嵌入结构组合

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,lastNamebio字段的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()方法,用于打印作者的title,content,fullNamebio

每当一个结构嵌入另一个结构时,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)
}

现在我们已经准备好了authorpost结构,让我们通过创建一个博客帖子来完成这个程序。

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()
}

Run in playground

上面程序中的主要功能是在第 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()
}

Run in playground

在上面的main function中,我们创建了一个作者author1和三个帖子post1,post2post3。最后我们在第 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 

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:咔叽咔叽_7647

查看原文:[译] part 27: golang 的面向对象 -- 组合取代继承

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1680 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏