面向过程与面向对象函数的区别
package main
import "fmt"
//面向过程
func Add01(a, b int) int {
return a + b
}
//面向对象,方法:给某个类型绑定一个函数
type long int
//a为接收者,接收者就是传递的一个参数
func (a long) Add01(b long) long {
return a + b
}
func main() {
result := Add01(1, 2)
fmt.Println("result = ", result)
//定义变量
var a long = 2
result1 := a.Add01(3)
fmt.Println("result1 = ", result1)
}
为结构体类型添加方法
/*
重点:
1. 带有接收者的函数叫方法
2. func (receiver ReceiverType) funcname (parameters) (results)
1) 参数receiver可以任意命名。
2) 参数receiver类型可以是T或T*。基类型T不能是接口或指针。
3) 只要接收者类型不同 函数名相同也是不同的方法
*/
package main
import "fmt"
type Person struct {
name string
sex byte
age int
}
func (p Person) PrintInfo() {
fmt.Println("p = ", p)
}
//通过一个函数给成员赋值
func (p *Person) SetInfo(name string, sex byte, age int) {
p.name = name
p.sex = sex
p.age = age
}
// pointer为接收者类型,本身不能为指针
// type pointer *int
// func (p Pointer) Add01() {
// }
//1.只要接收者类型不同 函数名相同也是不同的方法
type long int
func (a long) test1() {
}
//2.
type char byte
func (b char) test1() {
}
func main() {
//定义同时初始化
p := Person{"koko", 'n', 18}
p.PrintInfo()
//定义结构体变量
var p1 Person
(&p1).SetInfo("lucas", 'n', 14)
p1.PrintInfo()
}
值语义与引用语义
package main
import "fmt"
type Person struct {
name string
sex byte
age int
}
//值传递:一份拷贝
func (p Person) SetValue(name string, sex byte, age int) {
p.name = name
p.sex = sex
p.age = age
//%p为打印地址
fmt.Printf("SetValue &p = %p\n", &p)
}
//引用传递:传递自身地址
func (p *Person) SetPointer(name string, sex byte, age int) {
p.name = name
p.sex = sex
p.age = age
fmt.Printf("SetPointer p = %p\n", p)
}
func main() {
var s Person = Person{"koko", 'w', 16}
fmt.Printf("&s = %p\n", &s)
//s.SetValue("lucas", 'm', 12)
//fmt.Println("s = ", s)
s.SetPointer("lucas", 'm', 25)
fmt.Println("s = ", s)
}
指针变量的方法集
package main
import "fmt"
type Person struct {
name string
sex byte
age int
}
func (p Person) SetValue() {
fmt.Println("SetValue")
}
func (p *Person) SetPointer() {
fmt.Println("SetPointer")
}
func main() {
//结构体变量是一个指针变量,它能够调用哪些方法,这些方法就是一个集合,简称方法集
p := &Person{"koko", 'm', 13}
p.SetPointer()
(*p).SetPointer() //把(*p)转换成p
//内部做的转换:先把指针p转换成*p再调用
(*p).SetValue()
p.SetValue()
}
普通变量的方法集
package main
import "fmt"
type Person struct {
name string
sex byte
age int
}
func (p Person) SetValue() {
fmt.Println("SetValue")
}
func (p *Person) SetPointer() {
fmt.Println("SetPointer")
}
func main() {
p := Person{"koko", 'm', 13}
p.SetPointer() //先把p转换为&p 相当于(&p).SetPointer()
p.SetValue()
}
方法的继承
package main
import "fmt"
type Person struct {
name string
sex byte
age int
}
//Person类型,实现了一个方法
func (p *Person) Print() {
fmt.Printf("name = %s, sex = %c, age = %d\n", p.name, p.sex, p.age)
}
//Student继承了Person,则成员和方法都继承
type Student struct {
Person //匿名字段
id int
addr string
}
func main() {
s := Student{Person{"koko", 'm', 15}, 1, "shanghai"}
s.Print()
s.Person.Print()
}
方法的重写
package main
import "fmt"
type Person struct {
name string
sex byte
age int
}
//Person类型,实现了一个方法
func (p *Person) Print() {
fmt.Printf("name = %s, sex = %c, age = %d\n", p.name, p.sex, p.age)
}
//Student继承了Person,则成员和方法都继承
type Student struct {
Person //匿名字段
id int
addr string
}
//Student也实现了一个方法,这个方法与Person同名,这种方法叫重写
func (p *Student) Print() {
fmt.Printf("name = %s, sex = %c, age = %d, id = %d, addr = %s\n", p.name, p.sex, p.age, p.id, p.addr)
}
func main() {
s := Student{Person{"koko", 'm', 15}, 1, "shanghai"}
//就近原则:先找本作用域的方法,找不到再用继承的方法
s.Print()
//显式调用继承的方法
s.Person.Print()
}
方法值
package main
import "fmt"
type Person struct {
name string
sex byte
age int
}
func (p Person) SetValue() {
fmt.Printf("SetValue: %p, %v\n", &p, p)
}
func (p *Person) SetPointer() {
fmt.Printf("SetPointer: %p, %v\n", p, p)
}
func main() {
s := Person{"koko", 'm', 14}
fmt.Printf("main: %p, %v\n", &s, s)
pFunc := s.SetPointer // 方法值 不要带"()"
pFunc() //s.SetPointer()
vFunc := s.SetValue //方法值
vFunc() //等价于s.SetValue()
}
方法表达式
package main
import "fmt"
type Person struct {
name string
sex byte
age int
}
func (p Person) SetValue() {
fmt.Printf("SetValue: %p, %v\n", &p, p)
}
func (p *Person) SetPointer() {
fmt.Printf("SetPointer: %p, %v\n", p, p)
}
func main() {
s := Person{"koko", 'm', 14}
fmt.Printf("main: %p, %v\n", &s, s)
//方法值
//pFunc := s.SetPointer // 方法值 不要带"()"
//pFunc() //s.SetPointer()
//方法表达式
f := (*Person).SetPointer
f(&s) //显式把接收者传递过去 == s.SetPointer
f1 := (Person).SetValue
f1(s) //s.SetValue()
}