• 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编程-谢孟军

  • 相关阅读:
    day10 文件内指针移动 小练习 函数的基本使用 函数定义与调用的各三种形式 函数返回值 函数参数的使用
    day09 文件基本操作 上下文管理 文件的打开模式 文件修改的两种模式 今日作业
    day07 列表类型 练习题 元祖类型 元祖vs列表 字典类型 集合类型
    java笔试之参数解析(正则匹配)
    java笔试之提取不重复的整数
    java笔试之自守数
    java笔试之尼科彻斯定理
    java笔试之简单密码
    java笔试之求最大连续bit数
    java笔试之放苹果
  • 原文地址:https://www.cnblogs.com/piperck/p/6410157.html
Copyright © 2020-2023  润新知