Golang面向对象之类型、方法、多态

来源:互联网 发布:淘宝开店软件 编辑:程序博客网 时间:2024/05/22 08:15
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设计,懂绘画

原创粉丝点击