結構體和內嵌類型
結構體是Golang中面向對象的核心,Golang允許內嵌類型,內嵌可以理解爲使用組合來實現繼承,給出代碼示例:
package main
import "fmt"
type SmallFoo struct {
name string
money float64
}
func (smallFoo *SmallFoo) Talk() {
fmt.Printf("SmallFoo, name: %v, money: %v\n", smallFoo.name, smallFoo.money)
}
type Foo struct {
SmallFoo // 內嵌類型,相當於使用繼承
name string
age int
}
func (foo *Foo) SetName(name string) {
foo.name = name
}
func main() {
foo := new(Foo)
foo.money = 100.0
foo.SmallFoo.name = "smallFoo" // 有命名衝突,必須指明內嵌
foo.SetName("foo")
foo.Talk()
fmt.Println(foo)
}
結構體的方法
結構體的方法本身是把面向過程轉換到面向對象的。Older
函數和Foo::Older
方法是等價的。注意,如果以值聲明的方法,則每次都是複製,一般都用指針的方式。
package main
import "fmt"
type Foo struct {
age int
}
func (foo *Foo) Older(f *Foo) bool {
return foo.age > f.age
}
// foo是複製的,不論實際調用中的聲明是指針還是值
func (foo Foo) ChangeAgeFalse(age int) {
foo.age = age
}
// 利用指針纔是本身
func (foo *Foo) ChangeAge(age int) {
foo.age = age
}
func Older(f1, f2 *Foo) bool {
return f1.age > f2.age
}
func main() {
f1 := &Foo{age: 10}
f2 := &Foo{age: 5}
var b bool
b = f1.Older(f2)
fmt.Println(b)
b = Older(f1, f2)
fmt.Println(b)
f1.ChangeAgeFalse(12) // 即使是指針聲明,也是傳遞的值
fmt.Println(f1)
f1.ChangeAge(12)
fmt.Println(f1)
}
接口
Go語言的接口是隱式的,只要實現了接口的方法,就能實現轉化。
package main
import "fmt"
type Action interface {
Fly()
}
type AirCraft struct{}
func (ac AirCraft) Fly() {
fmt.Println("AirCraft Fly")
}
type AirCraftP struct{}
func (ac *AirCraftP) Fly() { // 雖然實現結構,但是必須以指針的形式傳入
fmt.Println("AirCraftP Fly")
}
type Figther struct {
weapon string
AirCraft
}
func foo(action Action) {
action.Fly()
}
func main() {
// 可以值或者指針
ac := AirCraft{}
foo(ac)
foo(&ac)
// 只能以指針傳入
acP := AirCraftP{}
foo(&acP)
// 內嵌類型也可以
f := Figther{}
foo(f)
foo(&f)
}