Go匿名成員

GoLang也提供了繼承的方法,不過是通過匿名組合的方式來實現(xiàn)的谜洽。

1. 非指針繼承

基本語法
// 基類
type Base struct {
    // 成員變量
}

func (b *Base) 函數(shù)名(參數(shù)列表) (返回值列表) {
    // 函數(shù)體
}

// 派生類
type Derived struct {
    Base //匿名:只有type萝映,沒有變量名
    // 成員變量
}

func (b *Derived) 函數(shù)名(參數(shù)列表) (返回值列表) {
    // 函數(shù)體
}

繼承規(guī)則

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) 函數(shù)名(參數(shù)列表) (返回值列表) {
    // 函數(shù)體
}

// 派生類
type Derived struct {
    *Base
    // 成員變量
}

func (b *Derived) 函數(shù)名(參數(shù)列表) (返回值列表) {
    // 函數(shù)體
}

繼承規(guī)則

1. 基類采用指針方式的組合析显,依然具有派生的效果鲫咽,只是派生類創(chuàng)建實例的時候需要外部提供一個基類實例的指針。

2. 其他規(guī)則與非指針方式組合一致谷异。

示例

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. 其他

名字覆蓋

// 上面說明了派生類成員方法名與基類成員方法名相同時基類方法將被覆蓋的情況分尸,這對于成員變量名來說,規(guī)則也是一致的歹嘹。
// 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
}

名字沖突

// 匿名組合相當于以其類型名稱(去掉包名部分)作為成員變量的名字箩绍。
// 那么按此規(guī)則,類型中如果存在兩個同名的成員尺上,即使類型不同材蛛,但我們預期會收到編譯錯誤。
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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市马绝,隨后出現(xiàn)的幾起案子豆赏,更是在濱河造成了極大的恐慌,老刑警劉巖富稻,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掷邦,死亡現(xiàn)場離奇詭異,居然都是意外死亡椭赋,警方通過查閱死者的電腦和手機抚岗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哪怔,“玉大人苟跪,你說我怎么就攤上這事÷В” “怎么了件已?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長元暴。 經常有香客問我篷扩,道長,這世上最難降的妖魔是什么茉盏? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任鉴未,我火速辦了婚禮枢冤,結果婚禮上,老公的妹妹穿的比我還像新娘铜秆。我一直安慰自己淹真,他們只是感情好,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布连茧。 她就那樣靜靜地躺著核蘸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪啸驯。 梳的紋絲不亂的頭發(fā)上客扎,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天,我揣著相機與錄音罚斗,去河邊找鬼徙鱼。 笑死,一個胖子當著我的面吹牛针姿,可吹牛的內容都是我干的袱吆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼距淫,長吁一口氣:“原來是場噩夢啊……” “哼绞绒!你這毒婦竟也來了?” 一聲冷哼從身側響起溉愁,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤处铛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拐揭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撤蟆,經...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年堂污,在試婚紗的時候發(fā)現(xiàn)自己被綠了家肯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡盟猖,死狀恐怖讨衣,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情式镐,我是刑警寧澤反镇,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站娘汞,受9級特大地震影響歹茶,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一惊豺、第九天 我趴在偏房一處隱蔽的房頂上張望燎孟。 院中可真熱鬧,春花似錦尸昧、人聲如沸揩页。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽爆侣。三九已至,卻和暖如春衷蜓,著一層夾襖步出監(jiān)牢的瞬間累提,已是汗流浹背尘喝。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工磁浇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人朽褪。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓置吓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親缔赠。 傳聞我的和親對象是個殘疾皇子衍锚,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內容