GO语言使用之面向对象编程(3)——方法
一、基本介绍
在某些情况下,我们要需要声明(定义)方法。比如Person结构体:除了有一些字段外( 年龄,姓名..),Person结构体还有一些行为比如:可以说话、跑步..,通过学习,还可以做算术题。这时就要用方法才能完成。
Golang中的方法是作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct
二、方法的声明(定义)语法
1、语法
func (recevier type) methodName(参数列表) (返回值列表){
方法体
return 返回值
}
2、参数说明:
1) 参数列表:表示方法输入
2) recevier type : 表示这个方法和type这个类型进行绑定,或者说该方法作用于type类型
3) receiver type : type可以是结构体,也可以其它的自定义类型
4) receiver : 就是type类型的一个变量(实例),比如 :Person结构体 的一个变量(实例)
5) 返回值列表:表示返回的值,可以多个
6) 方法主体:表示为了实现某一功能代码块
7) return 语句不是必须的。
3、案列代码:
type A struct {
Num int
}
func (a A) test() {
fmt.Println(a.Num)
}
func StructMethodDemo4() {
//方法的使用
var a A //创建变量
a.test() //调用
}
案例代码说明:
1) type A struct :说明A是一个结构体
2) func (a A) test() : 说明 test() 是一个方法, 和 A 结构体类型绑定/关联/ test方法作用在A结构体
三、快速入门的案列
/*结构体方法*/
type D struct {
Num int
}
func (a D) test() {
fmt.Println(a.Num)
}
func StructMethodDemo4() {
//方法的使用
var a D //创建变量
a.test() //调用
}
四、方法的调用和传参机制原理:(重要!)
方法的调用和传参机制和函数基本一样,不一样的地方是方法调用时,会将调用方法的变量,当做实参也传递给方法。
五、方法注意事项和细节讨论
1、结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
2、如程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理[案例+示意图]
type Person struct {
Name string
}
//给Person关联一个方法
//修改结构体变量的值,可以通过结构体指针的方式来处理
func (p *Person) test() { // Person 和 *Person是两种不同的数据类型
fmt.Printf("test的p的值=%p\n", p)
//因为p是指针,标准的修改方法
(*p).Name = "scott"
}
//如程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理
p := Person{"tom"}
fmt.Printf("main的p的地址=%p\n", &p)
//因为 test() 是和 *Person绑定
//标准的调用方式
(&p).test()
fmt.Printf("p的值=%v\n", p)
3、 Golang中的方法作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct, 比如int , float32等都可以有方法[案例]
/*
Golang中的方法作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,
而不仅仅是struct, 比如int , float32等都可以有方法
*/
type fl float64
func (f fl) test() {
fmt.Println("f=",f)
}
func (f *fl) test1() {
(*f)++
fmt.Println("f=",f)
fmt.Println("*f=",*f)
}
func StructMethodDemo1() {
var f fl = 12.3425
f.test()
f.test1()
}
4、方法的访问范围控制的规则,和函数一样。方法名首字母小写,只能在本包访问,方法首字母大写,可以在本包和其它包访问。
5、 如果一个类型实现了String() string 这个方法,那么fmt.Println默认会调用这个变量的String()进行输出。
type Car struct {
Name string
Price float64
}
//关联一个方法String方法,直接输出该结构体变量时,就会自动调用该方法.
func (car *Car) String() string {
str := fmt.Sprintf("name=[%v] price=[%v]", car.Name, car.Price)
return str
}
//如果一个类型实现了String() string 这个方法,那么fmt.Println默认会调用这个变量的String()进行输出
car := Car{"奔驰", 60.5}
fmt.Println(car)