Golang面向对象编程—方法

基本介绍

在某些情况下,我们需要声明(定义)方法。比如Person结构体:除了有一些字段外,Person结构体还有一些行为比如:可以说话,跑步,通过学习,还可以做算术题。这是就要用方法才能完成。
Golang中的方法是作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型都可以有方法,而不仅仅是struct。

方法的声明

func (receiver type)methodName(参数列表)(返回值列表){
    
    
    方法体
    return 返回值
}

说明:

  • 参数列表:表示方法输入
  • receiver type:表示这个方法和type这个类型进行绑定,或者说该方法作用于type.
  • receiver type:type可以是结构体,也可以是其他的自定义类型。
  • receiver:就是type类型的一个变量(实例),比如:Person结构体的一个变量。
  • 返回值列表:表示返回的值,可以是多个。
  • 方法主体:表示为了实现某一功能的代码块。
  • return 语句不是必须的。

方法快速入门案例

package main

import(
	"fmt"
)

type Person struct {
    
    
    name string
    age  int
}

//给Person结构体添加一个方法,输出个人基本信息
func (p Person) introduce(){
    
    
	fmt.Printf("大家好,我是%v,今年%v岁\n",p.name,p.age)
}

//给Person结构体添加一个cal方法,可以接受一个数n,计算1+2+3+...+n的值
func (p Person) cal(n int) {
    
    
	res := 0
	for i := 1; i <= n; i++{
    
    
		res += i
	}

	fmt.Println(p.name,"计算的结果 =", res)
} 

//给person结构体添加getSum方法,可以计算两个数的和,并返回结果
func (p Person) getSum(n1 int, n2 int) int{
    
    
	return n1 + n2
}
func main() {
    
    
  var p Person
  p.name = "Casey"
  p.age = 21
  //方法的调用
  p.introduce()
  p.cal(100)
  res := p.getSum(10,30)
  fmt.Println("res =", res)
}

运行结果:
在这里插入图片描述

方法的调用和传参机制原理

方法的调用和传参机制和函数基本一样,不一样的地方是方法调用时,会将调用方法的变量,当做实参也传递给方法。下面举例说明:
案例1:
getSum方法的执行过程和说明。

//给person结构体添加getSum方法,可以计算两个数的和,并返回结果
func (p Person) getSum(n1 int, n2 int) int{
    
    
	return n1 + n2
}
func main() {
    
    
  var p Person
  n1 := 10
  n2 := 20
  res := p.getSum(n1,n2)
  fmt.Println("res =", res)
}

在这里插入图片描述
说明:

  1. 在通过一个变量去调用方法时,其调用机制和函数一样。
  2. 不一样的地方是,变量调用方法时,该变量本身也会作为一个参数传递到方法(如果变量时值类型,则进行值拷贝,如果是引用类型,则进行地址拷贝)

方法和函数的区别

  1. 调用方式不一样。函数的调用方式:函数名(实参列表)。方法的调用方式:变量.方法名(实参列表)
  2. 对于普通函数,接收者为值类型时,不能讲指针类型的数据直接传递,反之亦然。
//不能接收指针类型的数据
func test1(p Person){
    
    
	fmt.Println(p.name)
}

func test2(p *Person){
    
    
	fmt.Println(p.name)
}
func main() {
    
    
   p := Person{
    
    
	   name : "Tome",
	   age : 18,
   }
   test1(p)
   test2(&p)
}
  1. 对于方法(如struct的方法),接收者为值类型是,可以直接用指针类型的变量调用方法。
//不能接收指针类型的数据
func (p Person)test1(){
    
    
	fmt.Println(p.name)
}

func (p *Person) test2(){
    
    
	fmt.Println(p.name)
}
func main() {
    
    
   p := Person{
    
    
	   name : "Tom",
	   age : 18,
   }
  p.test1()
  p.test2()
  //从形式上是传入地址,但本质上仍然是值拷贝
  (&p).test1()
  (&p).test2()
}

方法使用的注意事项

  1. 结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方法。
  2. Golang中的方法作用在指定的数据类型上(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct,比如int float32等都可以有方法。
type integer int
func (i integer) print(){
    
    
	fmt.Println("i =",i)
}
func (i *integer) change(){
    
    
	*i = *i + 1
}
func main() {
    
    
  var i integer  = 10
  i.print()
  i.change()
  fmt.Println("i =",i)
}

运行结果:
在这里插入图片描述

  1. 方法的访问范围控制的规则,和函数一样。方法名首字母小写,只能在本包访问,方法首字母大写,可以在本包和其它包访问。
  2. 如果一个类型实现了String()这个方法,那么fmt.Prinfln默认会调用这个变量的String()进行输出。
package main

import(
	"fmt"
)

type Person struct {
    
    
    name string
    age  int
}

func (p Person) String()string{
    
    
   str := fmt.Sprintf("name = %v,age = %v\n",p.name,p.age)
   return str
}
func main() {
    
    
	p := Person{
    
    
		name : "casey",
		age : 21,
	}
	fmt.Println(p)
}

运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44736475/article/details/114171556