Golang面向对象之类型、方法、多态
一、方法与函数
什么是方法?与函数的区别?
方法就是能够处理某种类型的变量或结构(以下结构也统称为变量)的函数,称为该类型的方法
这意味着,这个变量会传给这个函数,并且这个函数认识这个变量的内部构造
怎样使得一个函数成为一个类型的方法?
java和cpp将指向该类型变量的“this”指针作为隐含参数传入该函数
go将该类型变量的拷贝、或者指向该类型变量的指针作为“接收者”传入该函数
java和cpp将该函数藏在类中,以防止外界轻易访问
go中方法可以放置在任意位置
为什么需要一个函数成为一个类型的方法?
原因之一:多态性
如果只有独立分散的函数来处理各种类型,那么会有int_print(int a)、string_print(string a)、person_print(Person a)等等
如果把处理函数隐藏在类型中,则可以全部叫print()而不会名字冲突,这使得多态性成为可能:任意类型变量.print()
原因之二:安全性
函数藏身在类型中,可以对外只开放有限的访问权
二、完整地描述客观世界的实体
不仅仅实体本身的构造,还包括给实体配备的方法
实体本身的构成
汽车由发动机、油箱、车轮、车厢、方向盘构成
实体拥有的方法
拉货、加油、修车
广义地讲,不仅仅结构,原始类型,比如int,也是如此,包含一个值,以及加减乘除等方法,而string包含裁剪和连接等方法
不同语言对实体的描述
java、cpp通过类
类里面有各种变量数据
类里面有各种方法,这些方法通过this指针修改和处理类对象
go
通过原始类型或struct来描述单一或复杂实体的内部变量
类型变量通过“接收者”传递给函数,使得函数成为该类型的方法
也即一样有内部变量数据和可以操作这些变量的方法
三、Go的实体类型及其方法分类
注意,本质上Go仅仅有值拷贝传递。引用传递或指针传递在实际上都是指针的值拷贝传递
相当于值拷贝传递和指针传递被显式地区分开了
这样的好处是什么?可能是值传递缺省的安全,因为原变量不可能被修改
坏处是什么?要想通过方法修改一个变量或字段,必须增加一个指针字段来指向它?
或者只是增加传递指针的方法,使用“&字段名”来调用?
实体类型T
var i T
值拷贝传递后,方法拿到的是i的值拷贝,因此可能的方法包括所有接收者为T型的函数。原始的T型变量不可能被修改
指向实体类型的指针
var i *T
值拷贝传递后,方法拿到的是指向T型变量的指针i,因此可能的方法包括所有接收者为*T的函数,修改“*i”时会修改原始的T型变量
由于拿到i后,还可以通过“v = *i”来生成一个等值拷贝的T型变量
因此本类指针的方法还能包括所有接收者为T型的函数,自然原始变量也不会被修改
Go规范的英文原文是:
Such a function indirects through the receiver to create a value to pass as the receiver to the underlying method;
the method does not overwrite the value whose address is passed in the function call.
感觉是这个意思:
func(tv *T, a int) int {
var v
v = *tv // 在函数的开头生成了一个局部变量v
return func_real(v, a) // 余下的代码使用局部变量v,而不是“*tv”所指向的值
}
interface接口类型
var i I
此刻的i完全不同于实体变量或其指针
i本质上是一指针,可以指向任何包含了接口I的变量
i的方法就是接口I包含的方法
四、interface接口
什么是interface?
interface是一个接口,规定了一组方法的外观,或说调用格式,但不实现这些方法
类似文件系统的接口,无论底层是什么文件格式,总有open()、close()、read()、write()
凡是有open()、close()、read()、write()这组interface的任何IO设备均可看成文件系统
由此形成了多态性
通过interface来对实体按外部方法配备进行分类
type 软件工程师 interface {
java编程()
go编程()
加班()
写文档()
}
type 产品设计师 interface {
UI设计()
绘画()
}
interface变量
可能是一个指针,可以指向任何实现了该interface的实体,而不管实体本身是怎样的
var i 软件工程师 // 以后 i 可以指向任何软件工程师,可能是任何实体,不局限于人
i = 小明 // 或小王、火星人、机器人、一条聪明的狗,只要会java和go编程,会写文档会加班
var j 产品设计师 // 以后 j 可以指向任何产品设计师,可能是任何实体,不局限于人
j = 小张 // 也可能是小明,或其他任何人,或动物或狗,只要懂UI设计,懂绘画
一、方法与函数
什么是方法?与函数的区别?
方法就是能够处理某种类型的变量或结构(以下结构也统称为变量)的函数,称为该类型的方法
这意味着,这个变量会传给这个函数,并且这个函数认识这个变量的内部构造
怎样使得一个函数成为一个类型的方法?
java和cpp将指向该类型变量的“this”指针作为隐含参数传入该函数
go将该类型变量的拷贝、或者指向该类型变量的指针作为“接收者”传入该函数
java和cpp将该函数藏在类中,以防止外界轻易访问
go中方法可以放置在任意位置
为什么需要一个函数成为一个类型的方法?
原因之一:多态性
如果只有独立分散的函数来处理各种类型,那么会有int_print(int a)、string_print(string a)、person_print(Person a)等等
如果把处理函数隐藏在类型中,则可以全部叫print()而不会名字冲突,这使得多态性成为可能:任意类型变量.print()
原因之二:安全性
函数藏身在类型中,可以对外只开放有限的访问权
二、完整地描述客观世界的实体
不仅仅实体本身的构造,还包括给实体配备的方法
实体本身的构成
汽车由发动机、油箱、车轮、车厢、方向盘构成
实体拥有的方法
拉货、加油、修车
广义地讲,不仅仅结构,原始类型,比如int,也是如此,包含一个值,以及加减乘除等方法,而string包含裁剪和连接等方法
不同语言对实体的描述
java、cpp通过类
类里面有各种变量数据
类里面有各种方法,这些方法通过this指针修改和处理类对象
go
通过原始类型或struct来描述单一或复杂实体的内部变量
类型变量通过“接收者”传递给函数,使得函数成为该类型的方法
也即一样有内部变量数据和可以操作这些变量的方法
三、Go的实体类型及其方法分类
注意,本质上Go仅仅有值拷贝传递。引用传递或指针传递在实际上都是指针的值拷贝传递
相当于值拷贝传递和指针传递被显式地区分开了
这样的好处是什么?可能是值传递缺省的安全,因为原变量不可能被修改
坏处是什么?要想通过方法修改一个变量或字段,必须增加一个指针字段来指向它?
或者只是增加传递指针的方法,使用“&字段名”来调用?
实体类型T
var i T
值拷贝传递后,方法拿到的是i的值拷贝,因此可能的方法包括所有接收者为T型的函数。原始的T型变量不可能被修改
指向实体类型的指针
var i *T
值拷贝传递后,方法拿到的是指向T型变量的指针i,因此可能的方法包括所有接收者为*T的函数,修改“*i”时会修改原始的T型变量
由于拿到i后,还可以通过“v = *i”来生成一个等值拷贝的T型变量
因此本类指针的方法还能包括所有接收者为T型的函数,自然原始变量也不会被修改
Go规范的英文原文是:
Such a function indirects through the receiver to create a value to pass as the receiver to the underlying method;
the method does not overwrite the value whose address is passed in the function call.
感觉是这个意思:
func(tv *T, a int) int {
var v
v = *tv // 在函数的开头生成了一个局部变量v
return func_real(v, a) // 余下的代码使用局部变量v,而不是“*tv”所指向的值
}
interface接口类型
var i I
此刻的i完全不同于实体变量或其指针
i本质上是一指针,可以指向任何包含了接口I的变量
i的方法就是接口I包含的方法
四、interface接口
什么是interface?
interface是一个接口,规定了一组方法的外观,或说调用格式,但不实现这些方法
类似文件系统的接口,无论底层是什么文件格式,总有open()、close()、read()、write()
凡是有open()、close()、read()、write()这组interface的任何IO设备均可看成文件系统
由此形成了多态性
通过interface来对实体按外部方法配备进行分类
type 软件工程师 interface {
java编程()
go编程()
加班()
写文档()
}
type 产品设计师 interface {
UI设计()
绘画()
}
interface变量
可能是一个指针,可以指向任何实现了该interface的实体,而不管实体本身是怎样的
var i 软件工程师 // 以后 i 可以指向任何软件工程师,可能是任何实体,不局限于人
i = 小明 // 或小王、火星人、机器人、一条聪明的狗,只要会java和go编程,会写文档会加班
var j 产品设计师 // 以后 j 可以指向任何产品设计师,可能是任何实体,不局限于人
j = 小张 // 也可能是小明,或其他任何人,或动物或狗,只要懂UI设计,懂绘画
有疑问加站长微信联系(非本文作者)