Golang面向對象編程之繼承&虛基類【組合&接口】

  • 2019 年 12 月 12 日
  • 筆記

[TOC]

Golang面向對象編程之繼承&虛基類【組合&接口】

201808

相關說明

Golang裏面沒有像C++一樣有繼承相關的概念,但是我們卻可以實現繼承相關的用法,這就要用到struct、interface這兩個結構。

Golang裏面有組合的概念,也就是一個struct 裏面可以包含一個或者多個struct,struct可以近似理解為面向對象編程中的class,但是不能等同,有很多區別。如果一個struct實現了某個接口的所有方法,那麼只要是包含這個struct的所有其他struct也都是實現了這個接口的所有方法

實現 class 類

要想實現class類的用法,那麼就要用到struct結構,通過給定struct定義某個成員變量或成員方法就可以實現類的方法

  1. 通過type struct 定義一個struct【類】 type rsaSecurity struct { }
  2. 再定義一個這個類的變量,也就是對象 var RsaSecuritySrv rsaSecurity 類似於構造函數的定義,也可以通過new一個對象來使用,二選一。
  3. 實現一個這個struct類的方法,需要注意要顯示的聲明所屬對象,即(rs *rsaSecurity) // 加密 func (rs *rsaSecurity) RsaEncrypt(origData []byte) ([]byte, error) { //解密pem格式的公鑰 block, _ := pem.Decode(publicKey) if block == nil { return nil, errors.New("public key error") } // 解析公鑰 pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } // 類型斷言 pub := pubInterface.(*rsa.PublicKey) //加密 return rsa.EncryptPKCS1v15(rand.Reader, pub, origData) } 注意這裡是否使用指針,在於是否能夠是否需要徹底修改成員變量的值。
  4. 在任何需要調用這個成員方法的時候,通過對象來調用 func main() { data, _ := RsaSecuritySrv.RsaEncrypt([]byte(encrypt)) }

實現繼承

直接上代碼如下,很簡單,主要就是一個struct裏面包含一個匿名的struct,也就是通過匿名組合來實現

package main    import (      "fmt"  )    // 【基類】  //定義一個最基礎的struct類MsgModel,裏面包含一個成員變量msgId  type MsgModel struct {      msgId   int      msgType int  }    // MsgModel的一個成員方法,用來設置msgId  func (msg *MsgModel) SetId(msgId int) {      msg.msgId = msgId  }    func (msg *MsgModel) SetType(msgType int) {      msg.msgType = msgType  }    //【子類】  // 再定義一個struct為GroupMsgModel,包含了MsgModel,即組合,但是並沒有給定MsgModel任何名字,因此是匿名組合  type GroupMsgModel struct {      MsgModel        // 如果子類也包含一個基類的一樣的成員變量,那麼通過子類設置和獲取得到的變量都是基類的      msgId int  }    func (group *GroupMsgModel) GetId() int {      return group.msgId  }    /*  func (group *GroupMsgModel) SetId(msgId int) {      group.msgId = msgId  }  */    func main() {      group := &GroupMsgModel{}        group.SetId(123)      group.SetType(1)        fmt.Println("group.msgId =", group.msgId, "tgroup.MsgModel.msgId =", group.MsgModel.msgId)      fmt.Println("group.msgType =", group.msgType, "tgroup.MsgModel.msgType =", group.MsgModel.msgType)  }

實現虛基類的用法

Golang可以通過匿名組合來實現繼承。

Golang可以interface + struct來實現虛基類的用法,必須要實現interface中定義的方法。

1,定義一個interface接口MsgModel,包含了一些方法。

type MsgModel interface {      Persist(context context.Context, msg interface{}) bool      PersistOnSensitive(context context.Context, session_type, level, SensitiveStatus int32, msg interface{}) bool  }

3,定義一個類型msgModelImpl,用來實現接口類型

定義一個struct用來實現接口類型  type msgModelImpl struct{}      定義一個變量MsgModelImpl等於msgModelImpl,相當於可以通過MsgModelImpl來調用msgModelImpl的成員  var MsgModelImpl = msgModelImpl{}    實現接口的兩個方法  func (m msgModelImpl) Persist(context context.Context, msgIface interface{}) bool {  // 具體實現省略  }    func (m msgModelImpl) UpdateDbContent(context context.Context, msgIface interface{}) bool {  // 具體實現省略  }

4, 定義一個struct類型的msgService,包含上述接口類型MsgModel,相當於組合了。這樣的話,這個類型就需要要實現接口方法。

type msgService struct {     msgModel MsgModel  }

5, 再定義一個變量MsgService,首字母大寫,並且賦值為msgService對象,同時給成員msgModel賦值為上述已經實現了接口的struct對象MsgModelImpl。

將上述已經實現接口類型的類型(MsgModelImpl) 賦值給此變量(此變量並且要是包含了接口類型的類型), 然後這個變量就可以供外部調用  var  MsgService = msgService{          msgModel:  MsgModelImpl,  }

6, 通過MsgService調用接口方法

7, 小結:

  • MsgModel 是一個interface
    • interface 是一組抽象方法(未具體實現的方法/僅包含方法名參數返回值的方法)的集合
  • msgModelImpl是一個struct,它實現了MsgModel這個interface的所有方法
    • 如果實現了 interface 中的所有方法,即該類/對象就實現了該接口
  • MsgModelImpl是msgModelImpl這個struct的對象
  • msgService是一個struct,它包含了MsgModel,相當於組合
  • MsgService是msgService這個struct的對象,並對成員變量賦值