Go 没有沿袭传统面向对象编程中的诸多概念,也没有提供类( class ),但是它提供了结构体( struc),方法( method )可以在结构体上添加。与类相似,结构体提供了捆绑数据和方法的行为。
结构体类型也可以不包含任何字段,可以为类型关联上一些方法,方法需要有名字,不能被当作值来看待,最重要的是,它必须隶属于某一个类型。方法所属的类型会通过其声明中的接收者(receiver)声明体现出来。
1 2 3 4 5 6
| type People struct { }
func (p People) GetName() string { return "" }
|
方法的基本语法和使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package main
import "fmt"
type People struct { Name string Age int }
func (p People) GetName() string { return p.Name }
func main() { p := People{ Name: "hanpy", Age: 31, } name := p.GetName() fmt.Println(name) }
|
值接收者和指针接收者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package main
import "fmt"
type Person struct { age int }
func (p Person) howOld() int { return p.age }
func (p *Person) growUp() { p.age += 1 }
func main() { qcrao := Person{age: 18}
fmt.Println(qcrao.howOld())
qcrao.growUp() fmt.Println(qcrao.howOld())
stefno := &Person{age: 100}
fmt.Println(stefno.howOld())
stefno.growUp() fmt.Println(stefno.howOld()) }
|
不管方法的接收者是什么类型,该类型的值和指针都可以调用,不必严格符合接收者的类型。
两者分别在何时使用
如果方法的接收者是值类型,无论调用者是对象还是对象指针,修改的都是对象的副本,不影响调用者;如果方法的接收者是指针类型,则调用者修改的是指针指向的对象本身。
使用指针作为方法的接收者的理由:
- 方法能够修改接收者指向的值。
- 避免在每次调用方法时复制该值,在值的类型为大型结构体时,这样做会更加高效。
方法继承
匿名字段实现了一个方法,那么包含这个匿名字段的struct也能调用该匿名字段中的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package main
import "fmt"
type People struct { Name string Age int }
func (p People) Hello() { fmt.Printf("Hello Name is %s,Age is %d", p.Name, p.Age) }
type Student struct { People } type Teacher struct { People }
func main() { s := Student{People{"张学生", 15}} t := Teacher{People{"李老师", 35}} s.Hello() t.Hello() }
|
方法重写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| package main
import "fmt"
type People struct { Name string Age int }
func (p People) Hello() { fmt.Printf("Hello Name is %s,Age is %d", p.Name, p.Age) }
type Student struct { People }
func (s Student) Hello() { fmt.Println("子类的方法-Hello") }
type Teacher struct { People }
func (t Teacher) Hello() { fmt.Println("子类的方法-Hello") }
func main() { s := Student{People{"张学生", 15}} t := Teacher{People{"李老师", 35}} s.Hello() t.Hello() }
|