golang是可以實現繼承的,但是這種繼承並不是嚴格意義上的繼承,golang並不支持繼承特性,因而也沒有單繼承,多繼承,重寫方法等復雜概念。
下面通過一些例子來講解golang的繼承
組合繼承
(1)匿名繼承
type People struct{} func (p *People) ShowA() { fmt.Println("showA") p.ShowB() } func (p *People) ShowB() { fmt.Println("showB") } type Teacher struct { People } func (t *Teacher) ShowB() { fmt.Println("teacher showB") } func main() { t := Teacher{} t.ShowA() //showA\nshowB t.People.ShowA() //showA\nshowB t.ShowB() //teacher showB t.People.ShowB() //showB }
解釋輸出結果:
t.ShowA() 輸出:showA\nshowB。 調用showA時,因為Teacher沒有ShowA()的方法,此時又匿名繼承了People,所以會調到People實現的ShowA方法去
t.People.ShowA() 輸出:showA\nshowB。 匿名繼承時指定調用的結構體方法,這時候一定會調用People上的ShowA方法,如果People沒有該方法會編譯報錯
t.ShowB() 輸出:eacher showB。 因為Teacher本身有實現ShowB方法,所以會調用到 Teacher的ShowB方法。
t.People.ShowB() 輸出:showB。 此時如果我們想調用People的ShowB方法只能時通過指定結構體的方法。
(2)有名繼承
type People struct{} func (p *People) ShowA() { fmt.Println("showA") p.ShowB() } func (p *People) ShowB() { fmt.Println("showB") } type Teacher struct { P People } func (t *Teacher) ShowB() { fmt.Println("teacher showB") } func main() { t := Teacher{} t.ShowA() //報錯 t.People.ShowA() //報錯 t.People.ShowB() //報錯 t.ShowA() // 報錯 t.ShowB() //teacher showB t.P.ShowA() //showA\nshowB t.P.ShowB() //showB }
輸出結果解釋:
t.ShowA() 結果:報錯。 Teacher沒有ShowA的方法,雖然People有,但是此時People不是匿名繼承 ,如果要要調用需要指定繼承事指定的名稱。
t.People.ShowA() 結果:報錯。 t里沒有這個對象,此時People在結構體的名稱為P,而不是People,此時的People是P的類型
t.People.ShowB() 結果:報錯。 同時上
t.ShowB() 結果:teacher showB。 調用teacher的ShowB方法
t.P.ShowA() 結果:showA\nshowB 。有名繼承,People是P的類型,此時調用People的ShowA方法
t.P.ShowB() //showB
同上
未完待續。。。