Golang 中的 面向對象: 方法, 類, 方法繼承, 接口, 多態的簡單描述與實現


前言:

Golang 相似與C語言, 基礎語法與C基本一致,除了廣受爭議的 左花括號 必須與代碼同行的問題, 別的基本差不多;

學會了C, 基本上萬變不離其宗, 現在的高級語言身上都能看到C的影子;


Golang 中的 面向對象

  • 什么是面向對象?

    • 面向對象是一種編程思想, 並不是某一種開發語言獨屬;
  • 那什么是對象? 

    • 對象,指的是客體。所謂客體是指客觀存在的對象實體和主觀抽象的概念。(擴展閱讀
    • 簡單理解就是, 抽象一個擁有多重屬性的客體, 將共有屬性抽離出來為一個類, 以便實現定義多個客體的功能。
  • 面向對象有哪些特征?

    • 面向對象 通常包括三個特征 繼承, 封裝 和 多態; (簡單理解)
      • 繼承: 由子類繼承父類的屬性/數據/方法等;
      • 封裝: 以最簡單的函數形式將方法展示出去, 而不需要使用者知道方法內有什么、由什么實現, 類似黑盒子, 只需知道怎么用, 毋需知道為什么;例如, 電動車充電器, 只需知道插上兩邊的插頭, 而不需要去理解如何變壓限流;
        • 在Go語言中, 通常使用接口的方式完成封裝;
      • 多態: 一種方法的多種表現形式, 可以看作是封裝后的方法的集合, 根據使用場景, 自動分發到某具體方法中; 即一個同樣的函數對於不同的對象可以具有不同的實現。
  • 為什么使用面向對象?

    • 面向對象是為了解決系統的可維護性,可擴展性,可重用性( 詳細資料)
    • 簡單理解: 以對象方法代替過程完成實現, 方便以后修改及復用
  • Go語言中的面向對象如何實現? 以簡單計算器為例                                                         

                                        

         

    • 抽象類型: 計算器, 可以抽象為 兩個數字, 一個運算符和結果返回值;
      • 父類: 兩個數字
      • 子類: 繼承父類
      • 子類的方法: 做出計算並輸出結果返回值
    • 定義方法, 對不同的運算符返回不同的運算結果
    • 封裝: 定義接口, 將子類方法進行封裝
    • 多態: 定義多態, 並將封裝好的接口作為形參, 實現多態; 可以簡單理解為 以接口作為形參的函數

基於面向對象的, Go語言實現簡單計算器

  1. 分析實現過程, 進行抽象化: 兩個數字, 一個運算符, 一個結果返回值

type BaseNum struct {
     num1 int
     num2 int
} // BaseNum 即為父類型名稱

type Add struct {
    BaseNum
} //加法子類, 定義加法子類的主要目的, 是為了定義對應子類的方法

type Sub struct {
    BaseNum
} //減法子類

  2. 定義子類方法, 實現運算及返回值

func (a *Add)Opt()(value int) {
    return a.num1 + a.num2
}//加法的方法實現

func (s *Sub)Opt()(value int) {
    return s.num1 + s.num2
}//減法的方法實現

    注意: 這里的方法名稱是一樣的, 這樣才能使用接口進行歸納;

  3. 封裝, 定義接口, 歸納子類方法為 接口

type Opter interface { //接口定義
    Opt()int      //封裝, 歸納子類方法, 注意此處需要加上返回值, 不然沒有辦法輸出返回值(因為方法中使用了返回值)
}

  4. 定義多態

func MultiState(o *Opter)(value int) { //多態定義, 可以簡單理解為以接口作為形參的函數, 方便學習
    value = o.Opt()
    return
}

  5.主函數及調用

func main(){
    var a Add = Add{BaseNum{2,3}}
   
 //使用Add對象方法
    value := a.Opt()

//使用接口
    var i Opter
    i = &a
    value := i.Opt()

//使用多態
    i = &a
    value := MultiState(i)
//輸出測試
    fmt.Println(value)
}

至此, 一個單純的面向對象的 簡單計算器完工;

引發的問題思考:

  為什么比面向過程復雜的多?是否有意義?

  答案是肯定的, 面向對象所擁有的擴展性與維護性是面向過程無法比擬的;

    假設我需要在以上加減法計算器上加一個乘法或者除法, 那么我們需要做的工作僅僅是新建一個類和對應的方法就可以了, 其余的事情已經由接口定義下過了;


點滴延伸:

  

三 面對對象編程,分為幾個步驟? 

 

面向對象是一種思想,他讓我們在分析和解決問題時,把思維和重點轉向現實中的客體中來,然后通過UML工具理清這些客體之間的聯系,最后用面向對象的語言實現這種客體以及客體之間的聯系。它分為面向對象的分析(OOA),面向對象的設計(OOD),面向對象的編程實現(OOP)三個大的步驟。

1、首先是分析需求,先不要思考怎么用程序實現它,先分析需求中穩定不變的客體都是些什么,這些客體之間的關系是什么。

2、把第一步分析出來的需求,通過進一步擴充模型,變成可實現的、符合成本的、模塊化的、低耦合高內聚的模型。

3、使用面向對象的實現模型 

 摘自http://www.cnblogs.com/seesea125/archive/2012/04/20/2458940.html

在上面的實例中, 我們提到了運算符, 並將運算符與輸入值和輸出值並列在一塊, 這是為什么呢?

因為我們可以通過實現模型來完成更加簡潔的寫法:

下面實例使用工廠模式來解決計算器的問題:

package main

import "fmt"

/*
    實例: 面向對象的計算器實現

        1.定義父類
        2.定義子類,以及子類的方法 運算實現
        3.定義接口, 歸納 子類方法
        4.定義空類, 定義空類的方法,即 工廠模式, 將 運算符 與 數值 分開處理, 以運算符來分發方法, 方便調用
        5.定義一個多態, 將接口歸納, 方便調用
        6.主函數, 初始化, 調用工廠模式, 進行驗證

 */

 //父類
 type BaseNum struct {
     num1 int
     num2 int
 }

 //加法子類
 type Add struct {
     BaseNum
 }

 //減法子類
 type Sub struct {
     BaseNum
 }

 //子類方法
 func (a *Add)Opt() int {
     return a.num1 + a.num2
 }

 func (s *Sub)Opt() int {
     return s.num1 - s.num2
 }

 //定義接口, 即封裝

 type Opter interface {
     Opt() int
 }

 //定義多態
 func MultiState(o Opter) int{
     value:=o.Opt()
     return value
 }

 //定義空類 以產生 工廠模式 的方法
 type Factory struct {

 }

//⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️ func (f
*Factory)FacMethod(a,b int,operator string) (value int){ var i Opter switch operator { case "+": var AddNum Add = Add{BaseNum{a,b}} i = &AddNum case "-": var SubNum Sub = Sub{BaseNum{a,b}} i = &SubNum } //接口實現 : value = i.Opt() value = MultiState(i) //多態實現 return } //⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️ func main() { var a Factory value := a.FacMethod(20,3,"-") fmt.Println(value) }

上面的代碼中, 我們看到 Factory 部分, 先定義了一個空類以完成對平級方法的調用, 而后定義了一個方法;

此方法代替了主函數中每次調用前的初始化操作, 而且, 在主函數中, 也完全不需要知道其中的實現過程;


 

基於本實例的簡單分析, 及對Golang面向對象簡單圖示:


 

 

小結:

  至此, 關於Golang中的面向對象有了一個基礎的認識, 但是對於面向對象本身還是需要多加鞏固和練習; 


學習是為了寫代碼, 不多寫代碼怎么學習;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM