go物件導向方法的呼叫

JasBin2008發表於2020-10-26

go物件導向方法的呼叫

在物件導向三大特徵(封裝、繼承和多型)裡面,go語言只有封裝這個功能。但可以使用匿名欄位包含,間接實現繼承。

type Resouce struct {
	_ uint8
	id int
}

type User struct {
	Resouce //匿名欄位,User間接繼承自Resource
	name string
}

// 接收者型別為 User 時,可訪問方法集全部為 User 的方法,簡稱 T 方法
// 接收者型別型別 *User 時,可訪問方法集為 User 和 *User 的方法,簡稱 T + *T 方法。
// 接收者型別型別 Manager 包含匿名欄位 User,則 Manager 方法集包含 User 方法。
// 接收者型別型別 Manager 包含匿名欄位 *User,則 Manager 方法集包含 T + *T 方法。
// 不管嵌入 User 或 *User,*Manager 方法集總是包含 T + *T 方法。

func (self *User) ToString() string {
	return fmt.Sprintf("User = %p, %v", self, self)
}

func (self User) TestValue() {//User拷貝
	fmt.Printf("TestValue: %p, %v\n", &self, self)
}

type Manager struct {
	User//匿名欄位
	title string
}

func (self *Manager) ToString() string {
	return fmt.Sprintf("Manager = %p, %v", self, self)
}

func main() {
	m := Manager{User{Resouce{id:1}, "jorn"}, "zhang"}
	fmt.Println(m.ToString())
	fmt.Println(m.User.ToString()) //通過匿名欄位,獲得和繼承類似的利用能力

	//呼叫方法一:instance.method(args...)
	mInstance := m.ToString()
	m.name = "huangbin"
	fmt.Println(mInstance)
	fmt.Println(m.ToString())

	//呼叫方法二:<type>.func(instance, args...)
	mFunc := (*User).ToString
	fmt.Println(mFunc(&m.User))

	mFunc2 := (User).TestValue
	mFunc2(m.User)
}

相關文章