传统的面向对象编程
intint
对象可以使用属于它的普通变量来存储数据。这种从属于对象或类的变量叫作字段(Field)。对象还可以使用属于类的函数来实现某些功能,这种函数叫作类的方法(Method)。这两个术语很重要,它有助于我们区分函数与变量,哪些是独立的,哪些又是属于类或对象的。总之,字段与方法通称类的属性(Attribute)。
方法
在 Golang 中,方法是作用在接收者(receiver)上的一个函数,接收者是某种类型的变量;接收者可以是任意类型(指针、接口除外),包括结构体类型、函数类型、可以是 int ,boll,string或数组别名类型。
- 接收者不能是一个接口类型,因为接口是一个抽象定义,方法却必须要具体实现
- 接收者不能是一个指针类型,但可以是任何其他类型允许的指针
方法重载
Add*denseMatrix*sparseMatrix
//a是接收器变量,*denseMatrix和*sparseMatrix是接收器类型,Add是方法,b Matrix是参数列表,Matrix是返回参数
func (a *denseMatrix) Add(b Matrix) Matrix
func (a *sparseMatrix) Add(b Matrix) Matrix
接收器的标准格式
recvreceiver_typemethodNameparamater_listreturn_value_list
func (recv receiver_type)methodName(paramater_list)(return_value_list) {...}
接收器的类型
在计算机中,小对象由于值复制时的速度较快,所以适合使用非指针接收器,大对象因为复制性能较低,适合使用指针接收器,在接收器和参数间传递时不进行复制,只是传递指针。
//定义TwoInts结构体
type TwoInts struct {
a int
b int
}
func main(){
two1 := new(TwoInts)//实例化,返回指针*TwoInts
two1.a = 12
two1.b = 10
//调用AddThem方法
fmt.Println(two1.AddThem())
//调用AddToParam方法
fmt.Println(two1.AddToParam(20))
two2 := TwoInts{3,4} //实例化,返回结构体TwoInts{3,4}
//调用AddThem方法
fmt.Println(two2.AddThem())
}
//指针接收器的两个值相加方法
func (tn *TwoInts)AddThem()int{
return tn.a + tn.b
}
//指针接收器的三个值相加方法
func (tn *TwoInts)AddToParam(param int)int{
return tn.a + tn.b + param
}
/*
22
42
7
*/
// 定义点结构
type Point struct {
X int
Y int
}
// 非指针接收器的加方法
func (p Point) Add(other Point) Point {
// 成员值与参数相加后返回新的结构
return Point{p.X + other.X, p.Y + other.Y}
}
func main() {
// 初始化点
p1 := Point{3, 4}
p2 := Point{2, 5}
// 与另外一个点相加
result := p1.Add(p2)
// 输出结果
fmt.Println(result.X,result.Y,result)
}
/*
5 9 {5 9}
*/
### 函数和方法的区别
函数将变量作为参数:Function(recv);方法在变量上被调用:recv.Method1()
- 当接收者是指针时,方法可以改变接收者的值和状态。(对于方法来说)
- 当参数作为指针传递时,即通过引用调用时,函数也可以改变参数的状态。(对于函数来说)
### Golang设计模式之工厂方法
newNew
//不强制构造函数,首字母大写
type File struct {
fd int
name string
}
//构造工厂方法
func NewFile(fd int,name string) *File{
if fd < 0 {
return nil
}
return &File{fd,name}
}
func main() {
//调用工厂方法NewFile
f := NewFile(10,"./test.yxy")
fmt.Println(f)
//计算结构体占用多少内存
size := unsafe.Sizeof(File{})
fmt.Println(size)
}
/*
&{10 ./test.yxy}
24
*/
代码说明:
FileNewFile*Filemain
new
### 指针或值作为接收者
如果想要方法改变接收者的数据,就在接收者的指针类型上定义该方法。否则,就在普通的值类型上定义方法。
change()Bwrite()BB
type B struct {
thing int
}
func (b *B) change() {
b.thing = 1
}
func (b B) write() string {
return fmt.Sprint(b)
}
func main() {
var b1 B // b1是值
b1.change()
fmt.Println(b1.write())
b2 := new(B) // b2是指针
b2.change()
fmt.Println(b2.write())
}
/*
{1}
{1}
*/