结构体和内嵌类型
结构体是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)
}