方法和对象

去方法

就像其他任何Go函数一样定义方法。当Go函数在有限范围内定义或以特定类型附加时,称为方法。方法提供了一种将行为添加到用户定义类型的方法。方法实际上是包含在关键字func和函数名称之间声明的额外参数的函数。

在Go语言中,方法是一种特殊的函数,作用于某种类型的变量(称为接收器),该变量是放置在方法名称之前的额外参数,用于指定方法所附加的主持人类型。接收器类型可以是任何类型,而不仅仅是结构类型:任何类型都可以具有方法,甚至可以是函数类型或int,bool,字符串或数组的别名类型。

方法的一般格式为:
func(recv接收器类型)methodName(参数列表)(返回值列表){…}
接收方在func关键字之后的方法名称前的()中指定。

这是非结构类型的方法示例:

package main
import "fmt"

type 乘 int	

func (m 乘) 十次() int {
	return int(m * 10)
}

func main() {
	var num int
	fmt.Print("Enter any positive integer: ")
    fmt.Scanln(&num)
	mul:= 乘(num)
	fmt.Println("Ten times of a given number is: ",mul.tentimes())
}

运行该程序时,将得到以下输出:

C:\golang>go run example42.go
输入任何正整数:5
给定数字的十倍是:50

C:\golang>

关键字func和函数名称之间的参数称为接收器,并将函数绑定到 指定的类型。当函数具有接收者时,该函数称为方法。

Go中有两种类型的接收器:值接收器和指针接收器。在上面的程序中,使用值接收器声明了tentimes方法。十次接收方被声明为int类型的值。当使用值接收器声明方法时,该方法将始终针对用于进行方法调用的值的副本进行操作。

The 变量初始化为 类型。因此,可以使用以下方法访问tentimes方法 多.tentimes() 当我们打电话给 十次 方法,价值 是呼叫的接收者值, 十次 方法正在对此值的副本上进行操作。

这是一个程序,该程序显示了通过接收器参数(称为类型的方法集)附加到类型的方法的实现。

package main 
import "fmt" 
 
type salary float64 
func (s salary) total() total {    
   return total(s) 
} 
 
type total float64 
func (t total) hra() hra {
   t += t * 0.3   // 30% HRA Addition
   return hra(t)
} 
func (t total) salary() salary {   
   t -=t * 0.10    // 10% Tax Deduction  
   return salary(t) 
} 
 
type hra float64
func (h hra) basic() basic {
   h += h * 0.3   // 30% HRA Addition
  return basic(h)
}
func (h hra) total() total {   
  return total(h)
}

type basic float64 
func (b basic) total() total { 
   return total(b) 
} 
 
func main() { 
    fmt.Println("第一雇员的工资计算:")
    sal1 := basic(9000.00)
    fmt.Println(sal1.total())
    fmt.Println(sal1.total().hra().total())
    fmt.Println(sal1.total().hra().total().salary())

    fmt.Println("\n第二雇员的工资计算:")
    sal2 := basic(5000.00)
    fmt.Println(sal2.total())
    fmt.Println(sal2.total().salary())
} 
运行该程序时,将得到以下输出:
C:\golang>go run example43.go
第一雇员的工资计算:
9000
11700
10530

第二雇员的工资计算:
5000
4500

C:\golang>

方法重载

方法可能会根据接收器类型而重载,具有相同名称的方法可以存在于2种不同的接收器类型中,例如在同一包中允许这样做:
func(s * inclTax)薪金(e雇员)雇员
func(s * exclTax)薪金(e雇员)雇员

接收器参数可以作为基本类型的值或指针传递。指针接收器参数在Go中被广泛使用。

您也可以使用指针接收器声明方法。
package main
import "fmt" 

type 乘 int 
type addition int 

func (m *multiply) twice() { 
  *m = 乘(*m * 2) 
}

func (a *addition) twice() { 
  *a = addition(*a + *a)
} 

func main() { 
  var 多 乘 = 15 
  多.twice()
  fmt.Println(mul)

	
  var add addition = 15 
  add.twice()
  fmt.Println(add)
} 
运行该程序时,将得到以下输出:
C:\golang>go run example.go
30
30
C:\golang>

让我们再举一个例子,在该例子中,我们调用一个接收指向Struct的指针的方法。我们通过值和指针调用该方法,并且得到相同的结果。

声明带有指针接收器的方法的示例。
package main
import "fmt" 

type 乘 结构 {
	num int 
}

func (m *multiply) twice(n int) { 
  	m.num = n*2
}

func (m 乘) display() int{ 
  	return m.num
} 

func main() { 
  fmt.Println("按价值致电")	
  var 多1 乘	// 多1 is a value
  多1.twice(10)
  fmt.Println(mul1.display())

  fmt.Println("指针呼叫")	
  多2 := new(multiply) // 多2 is a pointer
  多2.twice(10)
  fmt.Println(mul2.display())
} 
运行该程序时,将得到以下输出:
C:\golang>go run example.go
Call by value
20
Call by pointer
20

在main()中,我们自己不必弄清楚是否要在指针上调用方法,Go会为我们做到这一点。 多1 是一个值, 多2 是一个指针,但是方法调用可以正常工作。

Go中的对象

没有一个类类型的概念可以用作Go中对象的基础。 Go中的任何数据类型都可以用作对象。结构 Go中的type可以接收一组定义其行为的方法。没有所谓的特殊类型 要么 目的 存在于GO中。 Go中的strct类型接近其他编程语言中通常称为对象的对象。 Go支持通常归因于面向对象编程的大多数概念。

借助软件包和可扩展类型系统等概念,Go的核心支持物理和逻辑模块化。因此我们能够在Go中实现模块化和封装。

新声明的名称类型不会继承其基础类型的所有属性,并且类型系统会对其进行不同的处理。因此,GO不支持 多态性 通过 遗产但是可以创建对象并使用诸如a之类的类型通过合成来表达其多态关系 结构接口.

让我们从下面的简单示例开始,演示如何将struct类型用作可以实现多态组合的对象。

package main
import "fmt"

type gadgets uint8 
const (    
    Camera gadgets = iota
    Bluetooth
    Media
    Storage
    VideoCalling
    Multitasking
    Messaging
) 
type mobile 结构 { 
    make string 
    model string 
} 
 
type smartphone 结构 { 
   gadgets gadgets    
}

func (s *smartphone) launch() {
   fmt.Println ("推出新的智能手机:") 
} 
 
type 安卓 结构 { 
   mobile 
   smartphone
   waterproof string
} 
func (a *android) samsung() { 
   fmt.Printf("%s %s\n", 
          a.make, a.model)           
} 
 
type 苹果手机 结构 { 
   mobile 
   smartphone 
   sensor int
} 
func (i *iphone) apple() { 
   fmt.Printf("%s %s\n",
          i.make, i.model) 
} 


func main() { 
   t := &android {}
   t.make ="Samsung"
   t.model ="Galaxy J7 Prime"
   t.gadgets = Camera+Bluetooth+Media+Storage+VideoCalling+Multitasking+Messaging
   t.launch()
   t.samsung() 
}
C:\golang>go run example.go
推出新的智能手机:
三星Galaxy J7 Prime

在上面的程序中组成 遗产 原理是用来实现 多态性 使用 类型嵌入 所支持的机制 结构 类型。在这里,每种类型都是独立的,并且被认为与所有其他类型都不同。上面的程序表明,类型 苹果手机安卓 是通过子类型关系移动的。

方法 t.launch() 但是,无论哪种类型, 苹果手机 也不 安卓,是名为launch()的方法的接收者。 launch()方法是针对智能手机类型定义的。由于智能手机类型已嵌入其中 苹果手机 也不 安卓,launch()方法在范围上被提升为这些封闭类型,因此可以访问。