Golang教程第27节--组合取代继承

原文来自:https://golangbot.com/inheritance/

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

上述代码片段,我们创建了一个结构体autuor,拥有成员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()方法,用来打印title,content,fullName和author.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结构体,现在我们可以实现一个博客帖子:

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运行

程序打印结果:

Title:  Inheritance in Go  
Content:  Go supports composition instead of inheritance  
Author:  Naveen Ramanathan  
Bio:  Golang Enthusiast  

结构体嵌套切片

我们可以进一步处理这个实例,用博客帖子的切片来创建一个网站。

首先定义website结构体。在main函数上方增加以下代码:

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.这是因为切片嵌套结构体时不能匿名(结构体可以匿名,如post中的author)。修改错误:

type website struct {  
        posts []post
}

给结构体website的切片成员增加成员变量名post。

现在修改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 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运行

程序执行结果:

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  

本节课程到此结束。Have a great day.

ps:新手翻译,欢迎大家指正!

下一节 Golang教程第28节--多态-Go面向对象编程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值