go介绍29——方法

面向过程与面向对象函数的区别

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()
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值