一看就懂系列之Golang的方法

转载请附上本文地址: https://blog.csdn.net/u011957758/article/details/81125101

前言

在Go里头是没有类的概念的,但是Go一样实现了同样的效果。
本文主要通过Go和PHP的对比来做笔记,致力于”一篇讲清楚go方法”,对于说phper的同学,看完印象会更深刻。

即将get到以下知识小点:
1.Go的方法 vs PHP的类
2.Go的继承 vs PHP的继承
3.重载?重写?
4.指针接收者的方法
5.封装&访问权限说明

正文

1.Go的方法 vs PHP的类

几乎所有广泛应用的语言都支持面向对象编程的思想。当然go也不例外。
在php中的class类的概念,对应到go里头就是方法的概念。

几个重点概念明确下:
1.方法其实是接收者(或者说receiver)上的一个函数。特殊类型的函数罢了
2.接受者必须是内置类型或者结构体的一个或者指针

在php中:

    class person {
        public function PrintName($name) {
            print_r($name);
        }
    }

    $person = new person();
    $person->PrintName('咖啡色的羊驼');

在go中:

    package main

    import (
        "fmt"
    )
    // 定义一个结构体,当作方法接收者
    type Person struct {}      

    // 方法声明其实就是在函数的基础上在func后面多增加定义接收者
    // func (r ReceiverType) funcName(parameters) (results)
    func (p Person) PrintName(name string) {
        fmt.Println(name)
    }

    func main() {
        cbs := Person {}            // 字面量的方式定义一个person类型
        cbs.PrintName("咖啡色的羊驼") // 直接调用方法
    }

是不是感觉很巧妙?go的方式实现了和php类一样的效果,底下可以跟一大丢函数。

2.Go的继承 vs PHP的继承

面向对象的思想里头有个概念叫做继承。

php例子就不写了,直接上go,show your code:

    package main

    import (
        "fmt"
    )

    type Person struct {
    }

    type SuperMan struct {
        Person      // 通过结构体内嵌包含的方式,来实现继承一样的效果
        Age int 
    }

    func (p Person) PrintName(name string) {
        fmt.Println(name)
    }

    func (s SuperMan) PrintAge() {
        fmt.Println(s.Age)
    }

    func main() {
        cbs := SuperMan{Age:18}
        cbs.PrintName("咖啡色的羊驼")       // 输出"咖啡色的羊驼"
        cbs.Person.PrintName("咖啡色的羊驼")// 输出"咖啡色的羊驼"
        cbs.PrintAge()                    // 输出18
    }



3.重载?重写?

重载简单的说就是重新定义一个函数名相同,参数个数或者类型不同的函数,并且存在于一个类中(go可以对应与同一个接受者中)。

!!!是的,go里头没有重载!!!

重写就是重新定义一个函数名相同,参数个数和类型也相同的函数,并且存在于同一个类或者子类中(翻译到go就是同一个接受者,或者继承的接受者)。

是的,重写go有了,

但是在go中不是真正严格意义上的面向对象,只是实现方式可以类比,所以go的重写也只是类比,参数不一定要相同,因为实际上还是看调用者调的方法所属的receiver。
~上代码:

    package main

    import (
        "fmt"
    )

    type Person struct {
    }

    type SuperMan struct {
        Person      // 通过结构体内嵌包含的方式,来实现继承一样的效果
        Age int 
    }

    func (p Person) PrintName(name string) {
        fmt.Println(name)
    }

    func (s SuperMan) PrintName(name string) {
        fmt.Println(name)
        fmt.Println(1) // 多来一个1以示区别
    }

    func (s SuperMan) PrintAge() {
        fmt.Println(s.Age)
    }

    func (s SuperMan) PrintName(name string) {
        fmt.Println(name,123)
    }

    func main() {
        cbs := SuperMan{Age:18}
        cbs := SuperMan{Age:12}
        cbs.Person.PrintName("咖啡色的羊驼1")// 输出"咖啡色的羊驼"
        cbs.PrintName("咖啡色的羊驼2")       // 输出"咖啡色的羊驼"和1
    }

4.指针接收者的方法

    type Person struct {
        Age float64
    }

    // 指针接收者
    func (p *Person) AgeIncr(num float64) {
        p.Age *= num
    }

    func main() {
        cbs := &Person{Age:18}
        cbs.AgeIncr(2)
        fmt.Println(*cbs)   // 输出 '{36}',说明初始化的值被改变了
    }

5.封装&访问权限说明

!!划重点!!

1.go语言只有一种控制命令可见性(public or private)的方式:定义的时候,首字母大写就是可以从包中导出(public),反之亦然。

2.go语言中封装的单元是,而不是类型。无论在函数内的代码,还是方法内,或者结构体内的字段对于同一个包中的所有代码都是可见的。

第一点很好理解,来一个例子,来证明一下第二点,:

    type Person struct {
        age float64
    }

    func (s Person) PrintAge() {
        fmt.Println(s.age)
    }

    func main() {
        cbs := Person{age:18}
        cbs.PrintAge()      
        // 输出18
        // 说明"方法当中可以访问结构当中的私有字段"
        // go语言中封装的单元是包,而不是类型
    }

你可能感兴趣的:(golang,一看就懂系列之Golang学习)