美文网首页
Go匿名成员

Go匿名成员

作者: 高稚商de菌 | 来源:发表于2018-03-08 22:49 被阅读0次

GoLang也提供了继承的方法,不过是通过匿名组合的方式来实现的。

1. 非指针继承

基本语法
// 基类
type Base struct {
    // 成员变量
}

func (b *Base) 函数名(参数列表) (返回值列表) {
    // 函数体
}

// 派生类
type Derived struct {
    Base //匿名:只有type,没有变量名
    // 成员变量
}

func (b *Derived) 函数名(参数列表) (返回值列表) {
    // 函数体
}

继承规则

1. 在派生类没有改写基类的成员方法时,相应的成员方法被继承。

2. 派生类可以直接调用基类的成员方法,譬如基类有个成员方法为Base.Func(),那么Derived.Func()等同于Derived.Base.Func()

3. 倘若派生类的成员方法名与基类的成员方法名相同,那么基类方法将被覆盖或叫隐藏,譬如基类和派生类都有成员方法Func(),那么Derived.Func()将只能调用派生类的Func()方法,如果要调用基类版本,可以通过Derived.Base.Func()来调用。

示例

package main

import "fmt"

type Base struct {
}

func (b *Base) Func1() {
    fmt.Println("Base.Func1() was invoked!")
}

func (b *Base) Func2() {
    fmt.Println("Base.Func2() was invoked!")
}

type Derived struct {
    Base
}

func (d *Derived) Func2() {
    fmt.Println("Derived.Func2() was invoked!")
}

func (d *Derived) Func3() {
    fmt.Println("Derived.Func3() was invoked!")
}

func main() {
    d := &Derived{}
    d.Func1()      // Base.Func1() was invoked!
    d.Base.Func1() // Base.Func1() was invoked!

    d.Func2()      // Derived.Func2() was invoked!
    d.Base.Func2() // Base.Func2() was invoked!

    d.Func3() // Derived.Func3() was invoked!
}

2. 指针方式组合

基本语法

// 基类
type Base struct {
    // 成员变量
}

func (b *Base) 函数名(参数列表) (返回值列表) {
    // 函数体
}

// 派生类
type Derived struct {
    *Base
    // 成员变量
}

func (b *Derived) 函数名(参数列表) (返回值列表) {
    // 函数体
}

继承规则

1. 基类采用指针方式的组合,依然具有派生的效果,只是派生类创建实例的时候需要外部提供一个基类实例的指针。

2. 其他规则与非指针方式组合一致。

示例

package main

import (
    "fmt"
    "log"
    "os"
)

type MyJob struct {
    Command string
    *log.Logger
}

func (job *MyJob) Start() {
    job.Println("job started!") // job.Logger.Println

    fmt.Println(job.Command)

    job.Println("job finished!") // job.Logger.Println
}

func main() {
    logFile, err := os.OpenFile("./job.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0)
    if err != nil {
        fmt.Println("%s", err.Error())
        return
    }
    defer logFile.Close()

    logger := log.New(logFile, "[info]", log.Ldate|log.Ltime|log.Llongfile)
    job := MyJob{"programming", logger}

    job.Start()
    job.Println("test finished!") // job.Logger.Println
}

3. 其他

名字覆盖

// 上面说明了派生类成员方法名与基类成员方法名相同时基类方法将被覆盖的情况,这对于成员变量名来说,规则也是一致的。
// package main

import "fmt"

type Base struct {
    Name string
}

type Base1 struct {
    Name string
}

type Derived struct {
    Base
    Base1
    Name string
}

func main() {
    d := &Derived{}
    d.Name = "Derived"
    d.Base.Name = "Base"

    fmt.Println(d.Name)      // Derived
    fmt.Println(d.Base.Name) // Base
}

名字冲突

// 匿名组合相当于以其类型名称(去掉包名部分)作为成员变量的名字。
// 那么按此规则,类型中如果存在两个同名的成员,即使类型不同,但我们预期会收到编译错误。
package main

import "log"

type Logger struct {
    Level int
}

type MyJob struct {
    *Logger
    Name string
    *log.Logger // duplicate field Logger
}

func main() {
    job := &MyJob{}
}
// 报错
reflect.StructOf: duplicate field X
// 同一深度,且没有被覆盖,直接调用d.Name还是会冲突
// 但是可以使用d.Base.Name
package main

import "fmt"

type Base struct {
    Name string
}

type Base1 struct {
    Name string
}

type Derived struct {
    Base
    Base1
    // Name string
}

func main() {
    d := &Derived{}
    d.Name = "Derived"
    d.Base.Name = "Base"

    fmt.Println(d.Name)      // Derived
    fmt.Println(d.Base.Name) // Base
}
ambiguous selector d.Name
来源: https://studygolang.com/articles/6330

相关文章

  • Go匿名成员

    GoLang也提供了继承的方法,不过是通过匿名组合的方式来实现的。 1. 非指针继承 基本语法 继承规则 示例 2...

  • 第04天(面对对象编程)_01

    01_匿名字段初始化.go 02_成员的操作.go 03_同名字段.go 04_非结构体匿名字段.go

  • Go基础编程---面向对象

    面向对象 Go中没有发封装、继承、多态,但是可以通过方法、匿名字段、接口实现,Go中偏向于面向接口编程 匿名字段(...

  • Go匿名函数

    GO语言的匿名函数就是闭包 基本概念 闭包是可以包含自由(未绑定到特定对象)变量的代码块,这些变量不在这个代码块内...

  • go 匿名函数

    Go支持匿名函数,如果我们某个函数只是希望使用一次,可以考虑使用匿名函数,匿名函数也可以实现多次调用1、匿名函数使...

  • struct 的匿名成员

    package main import"fmt" type Animal interface{ eat() } t...

  • 第02天(函数、工程管理)_04

    18_defer和匿名函数结合使用.go 19_获取命令行参数.go 20_局部变量.go 21_全局变量.go ...

  • 匿名函数

    new Student().say();匿名函数的局限性:匿名对象只能使用类中成员一次如果对象需要多次操作成员,就...

  • Golang基础(五)——函数二

    Golang基础(五)——函数二 @([07] golang)[Go总结] 匿名函数 匿名函数就是将一个函数直接赋...

  • 2020-06-27【内部类】

    成员内部类 局部内部类 匿名内部类

网友评论

      本文标题:Go匿名成员

      本文链接:https://www.haomeiwen.com/subject/qfyufftx.html