Go 分布式学习利器(12)-- Go语言的扩展和复用
Go語言無法天然支持繼承,但是又想要實現面向對象的特性。
即父類對象 使用子類對象初始化,那么該父類對象調用的函數就是子類實現的函數 ,從而滿足LSP(子類交換原則)。
案例一: Go語言 支持擴展父類的功能,如下代碼:
package oriented_testimport ("fmt""testing"
)// Pet 類
type Pet struct {
}func (p *Pet) Speak(){ // Pet類的函數成員fmt.Print("Pet speak.\n")
}func (p *Pet) SpeakTo(host string) { // Pet類的函數成員p.Speak()fmt.Println("Pet SpeakTo ", host)
}// Dog 擴展Pet的功能
type Dog struct {p *Pet
}// 擴展父類的方法
func (d *Dog) Speak(){d.p.Speak()
}// 擴展父類的方法
func (d *Dog) SpeakTo(host string) {d.Speak()fmt.Println("Dog Speakto ", host)
}func TestDog(t *testing.T) {dog := new(Dog)dog.SpeakTo("Test dog")
}
以上測試代碼的輸出如下:
Pet speak.
Dog Speakto Test dog
dog的SpeakTo中調用了dog 的Speak,其中調用了Pet的Speak,所以輸出正常。
Pet 和 Dog調用不會相互影響,完全由用戶決定。
但是這和我們所想需要的不同,Pet類有自己的方法,Dog類有自己的方法,兩者作用域完全不同。
這里Go語言推出了匿名嵌套類型,即Dog類不用實現自己的和Pet類同名的方法即可,通過在Dog類的聲明中變更Pet成員。
案例二: Go語言支持匿名函數類型
// Dog 擴展Pet的功能
type Dog struct {Pet
}
這樣即不需要Dog聲明自己的同名函數成員,默認的調用即為Pet成員函數的調用
package oriented_testimport ("fmt""testing"
)type Pet struct {
}func (p *Pet) Speak(){fmt.Print("Pet speak.\n")
}func (p *Pet) SpeakTo(host string) {p.Speak()fmt.Println("Pet SpeakTo ", host)
}// Dog 擴展Pet的功能
type Dog struct {Pet // 支持匿名嵌套類型,
}func TestDog(t *testing.T) {var dog Dogdog.Speak()dog.SpeakTo("Test dog")
}
最終的輸出如下:
=== RUN TestDog
Pet speak.
Pet speak.
Pet SpeakTo Test dog
--- PASS: TestDog (0.00s)
調用的都是Pet的成員函數,感覺像是繼承了,因為繼承默認就是子類能夠使用父類的公有成員。
在匿名嵌套類型下,我們想要完整嘗試一下Go語言是否真正支持繼承,可以像之前的代碼一樣在Dog中實現Pet的同名函數,且能夠通過父類對象調用子類的成員方法,像C++/Java這樣進行向上類型轉換(本身是不可能的,Go語言不支持顯式類型轉換)。
案例三: Go語言不支持繼承,如下代碼:
package oriented_testimport ("fmt""testing"
)type Pet struct {
}func (p *Pet) Speak(){fmt.Print("Pet speak.\n")
}func (p *Pet) SpeakTo(host string) {p.Speak()fmt.Println("Pet SpeakTo ", host)
}// Dog 擴展Pet的功能
type Dog struct {//p *PetPet // 支持匿名嵌套類型
}// 重載父類的方法
func (d *Dog) Speak(){fmt.Print("Dog speak.\n")
}// 重載父類的方法
func (d *Dog) SpeakTo(host string) {d.Speak()fmt.Println("Dog Speakto ", host)
}func TestDog(t *testing.T) {var dog Pet = new(Dog)dog.Speak()dog.SpeakTo("Test dog")
}
在最后的輸出會編譯出錯,不支持將Pet類型轉換為Dog類型:
./oriented_test.go:38:6: cannot use new(Dog) (type *Dog) as type Pet in assignment
總結一下,Go語言并不支持繼承,能夠支持接口的擴展 和 復用(匿名嵌套類型)
其中擴展 就是不同類實現相同的成員函數,能夠實現類似于案例一中的擴展接口形態。
復用則是通過匿名嵌套類型實現 類似于重載的功能,可以看看案例二的代碼。
總結
以上是生活随笔為你收集整理的Go 分布式学习利器(12)-- Go语言的扩展和复用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 女性不孕不育一般多久能治好
- 下一篇: Go 分布式学习利器(13)-- Go语