Go 面向对象 - 组合 替代 继承
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
、lastName
和 bio
字段的 author 结构体。 我们还添加了一个fullName() 方法,该方法接收一个 author类型的参数,它返回作者的全名。
下一步是创建 blogPost 结构体。
type blogPost struct {
title string
content string
author
}
func (b blogPost) details() {
fmt.Println("Title: ", b.title)
fmt.Println("Content: ", b.content)
fmt.Println("Author: ", b.author.fullName())
fmt.Println("Bio: ", b.author.bio)
}
blogPost 结构体具有 title
、content
字段。 它还具有嵌入式匿名字段 author
。 该字段表示 blogPost 结构体由 author 组成。 现在 blogPost 结构可以访问 author 结构的所有字段和方法。 我们还向 blogPost 结构添加了 details() 方法,该方法打印了作者的标题、内容、全名和简介。
每当一个结构体字段嵌入到另一个结构体中时,Go 都为我们提供了访问嵌入字段的选项,就好像它们是外部结构体的一部分一样。 这意味着 p.author.fullName() 可以用 p.fullName() 替换。 因此 details() 方法可以重写如下,
func (p blogPost) details() {
fmt.Println("Title: ", p.title)
fmt.Println("Content: ", p.content)
fmt.Println("Author: ", p.fullName())
fmt.Println("Bio: ", p.bio)
}
现在我们已经准备好了 author 和 blogPost 结构体,让我们通过创建一个博客文章来完成这个程序。
创建博客文章
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 blogPost struct { title string content string author } func (b blogPost) details() { fmt.Println("Title: ", b.title) fmt.Println("Content: ", b.content) fmt.Println("Author: ", b.fullName()) fmt.Println("Bio: ", b.bio) } func main() { author1 := author{ "Naveen", "Ramanathan", "Golang Enthusiast", } blogPost1 := blogPost{ "Inheritance in Go", "Go supports composition instead of inheritance", author1, } blogPost1.details() }
该程序运行结果如下
嵌入结构体切片
我们可以更进一步地使用这个示例,并使用一个博客文章的切片e)创建一个网站:)。
让我们先定义 website
结构体。 在现有程序的主函数上方添加以下代码并运行它。
type website struct {
[]blogPost
}
func (w website) contents() {
fmt.Println("Contents of Website\n")
for _, v := range w.blogPosts {
v.details()
fmt.Println()
}
}
添加上面代码后运行上面的程序时,编译器会如下错误
main.go:31:9: syntax error: unexpected [, expecting field name or embedded type
此错误是由切片[]blogPost
引起的。原因是不可能匿名嵌入切片。需要字段名。因此,让我们修复此错误并使编译器能编译通过。
type website struct {
blogPosts []blogPost
}
添加字段 blogPosts,它是一个切片 []blogPosts。
现在让我们修改 main 函数并为我们的新网站创建一些帖子。
修改main函数后的完整程序如下
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 blogPost struct { title string content string author } func (p blogPost) details() { fmt.Println("Title: ", p.title) fmt.Println("Content: ", p.content) fmt.Println("Author: ", p.fullName()) fmt.Println("Bio: ", p.bio) } type website struct { blogPosts []blogPost } func (w website) contents() { fmt.Println("Contents of Website\n") for _, v := range w.blogPosts { v.details() fmt.Println() } } func main() { author1 := author{ "Naveen", "Ramanathan", "Golang Enthusiast", } blogPost1 := blogPost{ "Inheritance in Go", "Go supports composition instead of inheritance", author1, } blogPost2 := blogPost{ "Struct instead of Classes in Go", "Go does not support classes but methods can be added to structs", author1, } blogPost3 := blogPost{ "Concurrency", "Go is a concurrent language and not a parallel one", author1, } w := website{ blogPosts: []blogPost{blogPost1, blogPost2, blogPost3}, } w.contents() }
运行结果如下
在上面的 main 函数中,我们创建了一个作者 author1 和三个帖子 post1、post2 和 post3。 最后,我们中创建了网站 w
。
相关文章
在 JavaScript 中验证 Google ReCaptcha 第 2 版
发布时间:2024/03/23 浏览次数:193 分类:JavaScript
-
本文演示了如何在 JavaScript 中验证 Google Recaptcha。
C# 中的 goto 语句
发布时间:2024/02/02 浏览次数:184 分类:编程语言
-
本教程演示了如何在 C# 中使用 goto 以及何时使用它会有所帮助本教程将演示如何在 C# 中使用 goto 语法,并提供一些代码中的实际使用示例。
在 Python 中是否存在 goto 语句
发布时间:2023/12/20 浏览次数:197 分类:Python
-
本文为你提供了 Python 中是否存在 goto 语句的答案。本文为你提供了 Python 中是否存在 goto 语句的答案。基本上,Python 不支持 goto 语句。
避免 Python中的 TypeError: Input Expected at Most 1 Argument, Got 3 错误
发布时间:2023/07/08 浏览次数:671 分类:Python
-
Python 中避免 TypeError: input Expected atmost 1 argument, got 3 Error在Python编程中,我们有两个内置方法来获取用户的输入:input(prompt)和 raw_input(prompt)。
使用 Python 将文件上传到 Google 云端硬盘
发布时间:2023/06/15 浏览次数:544 分类:Python
-
本文将介绍我们如何使用 Python 将文件上传到云盘,以 Google Drive 为例。 为此,我们将使用 Google Drive API。
Python 错误 Valueerror: Expected 2d Array, Got 1d Array Instead
发布时间:2023/05/30 浏览次数:293 分类:Python
-
当我们在 numpy 中传递一维数组而不是二维数组时,会发生错误 ValueError: Expected 2D array, got 1D array instead 。如您所知,每种编程语言都会遇到很多错误,有些是在运行时,有些是在编译时。 Pyth