Golang的面向对象实践method

最近在系统的学习go的语法,一切都弄好了之后准备弄个im项目出来玩。在这个过程中会把看到有趣的写法和语法啥的拿出来分析一下。

我一直以为go语言对面向对象没有支持,但是后面看到了类似类的概念,method特性以及其接受参数的reciver。

使用method就可以将不同的函数和结构体联系起来。

其实我现在还是习惯把go里面申明的结构体想象成对象,因为感觉很像,就像python里面你申明了一个对象,他有各种各样的属性一样。要介绍method和reciver来看个例子:

package main

import "fmt"

type Rectangle struct {
    width, height float64
}

func area(r Rectangle) float64 {
    return r.width * r.height
}

func main() {
    r1 := Rectangle{12 , 2}
    r2 := Rectangle{9, 4}
    fmt.Println("Area of r1 is: ", area(r1))
    fmt.Println("area of r2 is: ", area(r2))
}

这个例子就是我们定义了一个Rectangle的结构体,他有两个float64的属性width 和 height。

现在我们定义一个area函数,注意这里这个area函数跟其他的函数没有任何关系,就是接受接收一个rectangle结构体作为参数,然后返回计算了面积。

有点面向对象经验的同学,现在肯定就在想了,感觉这个计算Rectangle面积其实应该是Rectangle这个类中的一个函数,调用这个类函数就可以计算长方形的面积。

是的,所以我们可以使用method将这个结构体和这个函数关联起来,来看下面的代码:

package main

import "fmt"

type Rectangle struct {
    width, height float64
}

func (r Rectangle) area() float64 {
    return r.width * r.height
}

func main() {
    r1 := Rectangle{12 , 2}
    r2 := Rectangle{9, 4}
    fmt.Println("Area of r1 is: ", r1.area())
    fmt.Println("area of r2 is: ", r2.area())
}

这里我们用method来实现了为Rectangle计算面积这件事情。这里我们指定reciver 是 Rectangle 可以注意到,最后我们在申明area这个函数的时候,已经不需要再传入参数了,可以直接从reciver接收的结构体进行获取。这个地方会感觉这里传入的结构体这里,有点像传入了一个self字段,然后我们拿着这个self字段像去python 函数里面获取对象本身的值即一个函数,去调用各种属性和参数。

另外method还支持继承和重写,行为都和python中类继承很像这里我再举一个例子:

package main

import "fmt"

type Human struct {
    name string
    age int
    phone string
}

type Student struct {
    Human
    school string
    loan float32
}

type Employee struct {
    Human
    company string
    money float32
}

//Human 对象实现Sayhi方法
func (h *Human) SayHi() {
    fmt.Printf("Hi, I am %s you can call me on %s
", h.name, h.phone)
}

//Human 对象实现Sing方法
func (h *Human) Sing(lyrics string) {
    fmt.Println("La la, la la la, la la la ...", lyrics)
}

func (h *Human) Guzzle(beerStein string) {
    fmt.Println("Guzzle Guzzle Guzzle...", beerStein)
}

func (e *Employee) SayHi() {
    fmt.Printf("Hi, I am %s, I work at %s. Call me on %s
", e.name, e.company, e.phone)
}

func main() {
    o := Employee{Human: Human{name: "piperck", age: 25, phone: "18202815178"}, company: "xcf", money: 100}
    o.Guzzle("XIBA")
    o.Sing("what what you say what")
}

可以注意到,在结构体里,使用匿名结构体包含了一下Employee ,然后申明了一个结构体Employee实例o就可以使用Human上的方法了,并且继承了这些方法。

总之感觉就和类中定义函数,类的继承一个感觉。当结构体中存在继承,那么被继承的结构体添加了method,继承的结构体也同时拥有了该method,并且也可以进行重写,覆盖父类method。

Reference:

Go Web编程-谢孟军

原文地址:https://www.cnblogs.com/piperck/p/6410157.html