Go 嵌入類型

     文章轉載地址:https://www.flysnow.org/2017/04/06/go-in-action-go-embedded-type.htmlhtml

     嵌入類型或嵌套類型,這是一種能夠把已有類型的聲明嵌入到新的類型裏的一種方式,這種功能對代碼複用很是函數

重要htm

     在其餘語言中,有繼承的概念,可是在 Go 語言中沒有繼承的概念,Go 提倡的代碼複用的方式是組合,因此,這blog

也是嵌入類型的意義所在,組合不是繼承,因此,Go 纔會更加靈活繼承

type Reader interface {
	Read(p []byte) (n int, err error)
}

type Writer interface {
	Write(p []byte) (n int,err error)
}

type Closer interface {
	Close() error
}

type ReadWriter interface {
	Reader
	Writer
}

type ReadCloser interface {
	Reader
	Closer
}

type WriteCloser interface {
	Writer
	Closer
}

  上面是標準 io 包裏,咱們經常使用的接口,能夠看到 ReadWriter 接口是嵌入 Reader、Writer 接口組合而成的新接口,這樣接口

咱們就不用在重複的定義被嵌入接口的方法,直接經過嵌入就能夠了。嵌入類型一樣適用於結構體類型,看下面例子:string

type user struct {
	name string
	email string
}

type admin struct {
	user
	level string
}

  嵌入後,被嵌入的類型稱之爲內部類型,新定義的類型稱之爲外部類型,這裏 user 就是內部類型,而 admin 是外部類型it

       經過嵌入類型,與內部類型相關的字段、方法、標識符等都會被外部類型所擁有,就像外部類型本身的同樣,這樣就達到了io

代碼快捷複用組合的目的class

       同時,外部類型還能夠添加本身的方法,字段等,能夠很方便的擴展外部類型的功能

type user struct {
	name string
	email string
}

type admin struct {
	user
	level string
}

func main() {
	ad := admin{user{"張三","zhangsans@qq.com"},"管理員"}
	fmt.Println("能夠直接調用,名字是:",ad.name)
	fmt.Println("也能夠經過內部類型調用:",ad.user.name)
	fmt.Println("但新增的屬性只能直接調用:",ad.level)
}

  上面是嵌入類型的使用,在初始化的時候,咱們採用的是字面值的方式,先初始化 user 這個內部類型,再初始化

新增的 level 屬性

        對於內部類型的屬性和方法訪問上,咱們能夠採用外部類型直接訪問,也能夠經過內部類型進行訪問,可是咱們爲

外部類型新增方法屬性字段,只能使用外部類型訪問,由於內部類型沒有這些

       固然,外部類型也能夠聲明同名的字段或方法,來覆蓋內部類型,這種狀況方法比較多,以方法爲例:

type user struct {
	name string
	email string
}

type admin struct {
	user
	level string
}

func (u user) sayHello()  {
	fmt.Println("Hello,I am a user")
}

func (a admin) sayHello()  {
	fmt.Println("Hello,I am a admin")
}

func main() {
	ad := admin{user{"張三","zhangsans@qq.com"},"管理員"}
	ad.user.sayHello()
	ad.sayHello()
}

  內部類型 user 有一個 sayHello 方法,外部類型對其進行了覆蓋,同名重寫 sayHello,而後在 main 方法分別訪問這兩個

類型的方法,打印輸出:

Hello,I am a user
Hello,I am a admin

    從上面的輸出能夠看出,方法 sayHello 被覆蓋了

       嵌入類型還有一個強大的地方就是:若是內部類型實現了某個接口,那麼外部類型也被認爲實現了這個接口,以下示例:

type Hello interface {
	hello()
}

type user struct {
	name string
	email string
}

type admin struct {
	user
	level string
}

func (u user) hello() {
	fmt.Println("Hello, I am a user")
}

func sayHello(h Hello)  {
	h.hello()
}

func main() {
	ad := admin{user{"張三","zhangsans@qq.com"},"管理員"}
	sayHello(ad.user) // 使用 user 做爲參數
	sayHello(ad)      // 使用 admin 做爲參數
}

  新增一個 Hello 接口,而後讓 user 類型實現這個接口,最後定義了一個 sayHello 方法,它接受一個 Hello 類型的

參數,最後咱們在 main 函數調用的時候,發現無論是 user 類型吧,仍是 admin 類型做爲參數傳遞給 sayHello 都能正

常調用,這裏就能說名 admin 接口實現了接口 Hello,可是又沒有顯示聲明 admin 實現,因此這個實現是經過內部類型

user 實現的,由於 admin 包含了 user 全部方法和字段,因此也就實現了這個接口

相關文章
相關標籤/搜索