golang实现继承的方法:Go采用组合的方式表达继承的语义,代码为【type Cat struct {p *Pet}func (c *Cat) Catch(){fmt.Println("*****")}】。
golang实现继承的方法:
用封装的话题上来,转换成编程语言就是A把猫封装成宠物了,B把狗封装成宠物了,而 C需要宠物时,猫和狗都是宠物,最终结果要么是程序依旧正常运行,要么是程序意外挂掉了,因为很可能某一种宠物可能并不符合特定需求.
这种重复定义问题归咎于封装的标准不同,猫和狗两者的封装过程是独立进行的,并没有在一起商量着看看能不能继续抽象出通用模型,混乱的封装导致了猫是宠物,狗也是宠物.
这种多种相关概念的封装很容易出现此类问题,所以适当进行统一分析继续抽象出更高层次的封装概念尤为重要,基于此,原来的封装就能从这种通用概念中解放出来,仅仅保留自己的特色就好,大大简化了模型的语义.
普通封装的概念和更高层次的抽象封装概念的关系就是面向对象中的继承,即猫继承于宠物,表示猫不但拥有宠物的特点还有猫自己的亮点.
对于狗也是一样,狗是宠物,狗也是狗自己本身,体现了自己的特点.
Go
那Go是如何描述这种普通封装和抽象封装之间的关系呢?
肯定不是把猫定义成宠物,狗也定义成宠物那种方式!
Go 实现继承的语义不是通过 extends 关键字而是通过结构体组合的方式,请看相关代码.
宠物就应该能文能武,这里不关心结构体的字段,因而并没有定义相关字段.
type Pet struct { } func (p *Pet) Skill() { fmt.Println("能文能武的宠物") }
猫是能够抓老鼠的宠物,Go采用组合的方式表达继承的语义.
type Cat struct { p *Pet } func (c *Cat) Catch() { fmt.Println("老鼠天敌喵喵喵") }
狗是自带导航功能的宠物,看我导盲犬的超能力!
type Dog struct { p *Pet } func (d *Dog) Navigate() { fmt.Println("自带导航汪汪汪") }
接下来,C开始检验猫和狗作为宠物是否具备能文能武的基本要求,与此同时有没有自身的特色?
func TestExtendInstance(t *testing.T) { p := new(Pet) d := new(Dog) d.p = p // 自带导航汪汪汪 d.Navigate() // 能文能武的宠物 d.p.Skill() fmt.Println() c := new(Cat) c.p = p // 老鼠天敌喵喵喵 c.Catch() // 能文能武的宠物 c.p.Skill() }
上述结果证明,Go 语言虽然不支持 extends 关键字表达的继承特性,但是采用组合的方式也是可以实现继承语义的