Golang05-go语言方法

327 阅读3分钟

方法

GO语言有函数和方法,方法的本质也是函数。但是方法和函数又有点不同

2.1方法和函数在go中的区别

方法是一个类或者对象的行为。而函数是一段具有独立功能的代码块

方法有接收者,而函数没有

函数不可以重名而方法可以

package main

import "fmt"

type employee struct {
	name,currency string
	salary float64
}
//这个是函数
func printSalary(e employee)  {
	fmt.Printf("%s,%s,%.2f\n",e.name,e.currency,e.salary)
}
//这个是方法
func (e employee)printSalary()  {
	fmt.Printf("%s,%s,%.2f\n",e.name,e.currency,e.salary)
}

func main()  {
	emp:=employee{"JackMa","$",20000000}
	emp.printSalary()
	printSalary(emp)
}
/*
输出结果
JackMa,$,20000000.00
JackMa,$,20000000.00
*/

一段程序可以用函数来写,却还要使用方法,主要有以下两个原因。

  1. Go不是一种纯粹的面向对象语言,它不支持类。所以方法在实现类似于类的行行为。
  2. 相同名称的方法可以在不同类型上定义,而具有相同名称的函数不允许。比如求面积,圆和矩形的面积就不同
package main

import "fmt"

type Rectangle struct {
	width,height float64
}
type circle struct {
	radius float64
}

func (r Rectangle)area() float64 {
	return r.width*r.height
}

func (c circle)area() float64 {
	return c.radius*c.radius*3.14159265
}

func main()  {
	r1:=Rectangle{10,4}
	c1:=circle{10}
	fmt.Println("矩形的面积:",r1.area())
	fmt.Println("圆的面积:",c1.area())
}

/*
输出结果:
矩形的面积: 40
圆的面积: 314.159265

*/

若方法的接受者不是指针,实际只是获取了一个拷贝,而不能真正改变接受者中原来的数据。当指针作为接受者时,原来的值发生了改变。

package main

import "fmt"

type rectangle struct {
	width,height float64
}

func (r rectangle)setValue() {
	fmt.Printf("setValue方法中r的地址:%p\n",&r)	//0xc00000a0f0
	r.height=10
}
func (r *rectangle)setValue2() {
	fmt.Printf("setValue方法中的地址:%p\n",r)	//0xc00000a0b0
	r.height=20
}
func main()  {
	r1:=rectangle{5,8}
	r2:=r1
	fmt.Printf("r1的地址:%p\n",&r1)		//0xc00000a0b0
	fmt.Printf("r2的地址:%p\n",&r2)		//0xc00000a0c0
	r1.setValue()
	fmt.Println("r1.height=",r1.height)		//8
	fmt.Println("r2.height=",r2.height)		//8
	fmt.Printf("-------------------\n")
	r1.setValue2()
	fmt.Printf("*******************\n")
	fmt.Printf("r1.height=%f\n",r1.height)	//r1.height=20.000000
	fmt.Printf("r2.height=%f\n",r2.height)	//r2.height=8.000000
}


2.2 方法继承

方法是可以继承的,如果匿名字段实现了一个方法,那么包含这个匿名字段的struct也能调用该匿名字段中的方法。

package main

import "fmt"

type Human struct {
	name,phone string
	age int
}
type student struct {
	Human  //匿名字段
	school string
}

type Employee struct {
	Human	//匿名字段
	company string
}

func (h *Human) sayHi()  {
	fmt.Printf("大家好我是:%s,我%d岁了,我的联系方式是:%s\n",h.name,h.age,h.phone)
}

func main()  {
	s1:=student{Human{"JackMa","1388888888",13},"Mit"}
	e1:=Employee{Human{"PonyMa","1399999999",123},"shenzhen"}
	s1.sayHi()
	e1.sayHi()
}
/*
大家好我是:JackMa,我13岁了,我的联系方式是:1388888888
大家好我是:PonyMa,我123岁了,我的联系方式是:1399999999
*/


2.3 方法重写

package main

import "fmt"

type Person struct {
	name,phone string
	age int
}
type Student struct {
	Person
	school string
}
type Teachers struct {
	Person
	object string
}

func (h *Person)sayHello()  {
	fmt.Printf("大家好,我是%s,我是一个person,我今年%d岁了,我的联系方法是:%s\n",h.name,h.age,h.phone)
}

func (s *Student) sayHello()  {
	fmt.Printf("大家好,我是%s,我是一名学生,我今年%d岁了,我的联系方法是:%s\n",s.name,s.age,s.phone)
}

func (t *Teachers) sayHello()  {
	fmt.Printf("大家好,我是%s,我是一名老师,我今年%d岁了,我的联系方法是:%s\n",t.name,t.age,t.phone)
}


func main()  {
	s1:=Student{Person{"张三同学","13885555320",13},"清华大学"}
	t1:=Teachers{Person{"马老师","12345679810",28},"垄断学"}
	s1.sayHello()
	t1.sayHello()
}