《Go程序设计语言》 6 方法

Go语言的面向对象

  • 对象是拥有方阿飞的值或变量
  • 方法是一种特殊的函数

方法声明

与普通的函数声明相比,方法的声明需要在函数的名字前多加一个擦拭保护,表示将这个方法绑定在这个参数对应的类型上

func (p Point) Distance(q Point) float64 {
	return math.Hypot(q.X-p.X,q.Y-p.Y)
}
  • 附加的参数p称为方法的接收者,其作用和C++面向对象里的方法中的this是差不多意思
  • 类型拥有的所有方法名都必须是唯一的,但是不同类型可以有相同的方法名】

指针接收者的方法

在C++中,对象的方法由于会自动传一个this的指针进去,所以可以在方法中很轻松的修改“接收者”本身的值。而在Go中,由于接收者也作为一个参数出现了,其自然也是按值传递,所以要想对接收者本身做出更改,则必须声明指针作为接收者的方法

func (p *Point) ScaleBy(factor float64) {
	p.X *= factor
	p.Y *= factor
}

为了方便调用,以*T为接收者的方法可以接受T变量的调用,其中会自动执行(&t).somfunc;以T为接收者的方法可以接受*T变量的调用,其中会自动执行(*t).somfunc

  • nil也是合法的接收者,这是因为对于类似map,slice的类型,nil是有意义的零值(空表)

通过结构体内嵌组成类型

这一块的内容有点类似C++中,派生类的引用或指针可以隐式的向基类的转换,从而调用到基类的方法。但是作者这里又强调了,必须将Go语言的方法与面向对象的方法区别开来,因为在这里不存在基类和派生类,存在的是内嵌(组合)

考虑内嵌一个PointColoredPoint类型

type ColoredPoint struct {
	Point
	Color color.RGBA
}

我们可以通过类型为ColoredPoint的接收者调用内嵌类型Point的方法,该方法实际上直接的操作到ColoredPointPoint组件

var p ColoredPoint
p.ScaleBy(2)

实际上相当于自动生成了下面的代码

func (p *ColorPoint) ScaleBy(factor float64) {
	p.Point.ScaleBy(factor)
}

当查找方法时,会执行一个树形的搜索:先搜索当前类型有没有该名字的方法,然后进入内嵌的类型搜索。若同一搜索层级出现同名的方法,则会报错

方法变量与表达式

应用我们之前讲到的,函数也是值知识,并注意到方法也是一种特殊的值

方法变量

将方法绑定到一个特定的接收者上,并赋予新名字,使得新定义的函数可以只提供实参,接收者沿用我们绑定的接收者

p := Point{1,2}
distanceFromP := p.Distance
d := distanceFromP(p) //0

方法表达式

将一个方法“重命名”成一个函数,原来的接收者成为新函数的第一个形参,原来的形参成为新函数从第二个开始的形参。

distance := Point.Distace
d := distance(p,q)
  • 注意右侧要写成T.f(*T).f,其中T是方法绑定到的类型名

封装

我们知道,Go语言中唯一与变量可见性有关的,就是“大写字母开头的标识符可以从包中导出”,这告诉我们

  • 封装的单位是包
  • 我们可以使用结构体来达到封装一个对象的效果

比如

type IntStack struct {
	elements []int
}
  • 这时,在包内,我们可以通过s.elements访问到内部的组件,编写相关方法 。但是在包外,我们只能接触到IntStack,而接触不到其内部的实现细节。这其实就和private差不多了
  • 类似的,对于我们想要其成为“公有方法”和“公有部分”的标识符,我们使用大写;其它使用小写。同这一区别,我们就达到了我们熟悉的public:,private:效果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值