【Go語言】【15】GO語言的面向對象

GO是否是面向對象的語言?程序員

GO做者如是說:「是,也不是。」編程

正如前面所說:GO是一種面向類型的語言,它有類型和方法,但沒有類的概念,程序員能夠用一種面向對象的風格(或者說是方式)來編程,下面咱們從封裝性、繼承性和多態性三大面向對象的特性談談GO語言iphone

一、封裝性ide

       面向對象的語言中,「類」是基本單位,它把屬性、方法侷限在「類」中,並對外提供公共方法讓使用者操做對象。固然這一過程離不開修飾符:public、protected、private等。函數

       GO語言如何實現封裝性呢?它是經過結構體(struct)和爲類型添加方法的方式實現的。測試

       例如,封裝一個矩形(Rect)類,試想調用者會對矩形類作什麼操做呢?無非就是看看它的面積、周長之類的信息,那麼按照面向對象的編程思想來講,只要向使用者暴露getArea()、getPerimeter()方法便可,使用者無須接觸到矩形的長和寬。ui

/**spa

  * 定義一個結構體,裏面有兩個成員length和width3d

  */orm

type Rect struct {

        length, width int

}

接下來爲結構體定義兩個方法getArea()和getPerimeter(),分別用來讀取矩形的面積和周長

/**

  * 獲取矩形的面積

  */

func (r *Rect) GetArea() int {

        return r.length * r.width

}


/**

  * 獲取矩形的周長

  */

func (r *Rect) GetPerimeter() int {

        return (r.length + r.width) * 2

}

爲了讓該包以外的函數調用到GetArea()和GetPerimeter(),因此這裏函數的首字母大寫。同時爲告終構體初始化更面向對象些,再定義一個用於初始化結構體的方法NewRect()

/**

  * 初始化結構體Rect

  */

func NewRect(length, width int) *Rect {

        return &Rect{length, width}

}

通過這樣的封裝,使用者能夠以面向對象的方式調用Rect了 :)

/**

  * 使用者先引入Rect.go的路徑

  */

import (

        "cube"

        "fmt"

)


/**

 * 經過cube調用NewRect()生成*Rect對象

 */

func main() {

        r := cube.NewRect(10, 20)

        fmt.Println("面積:", r.GetArea(), "  周長:", r.GetPerimeter())

}


【備註】:

Rect.go和測試main.go路徑結構以下

wKioL1WpHPnTstkAAAAnAJYeePs897.jpg

其中Rect.go所屬包爲cube、main.go所屬包爲main


執行程序,運行結果以下:

wKioL1WpHarwUCv-AABTfzOr2QE794.jpg


二、繼承性

wKioL1Wpt9uz-QZHAABs_WAb8pQ174.jpg

       rect結構體定義兩個方法,分別用於獲取面積和周長,cube結構體也定義了兩個方法,一個是獲取體積,另外一個重寫父結構體rect的獲取周長:

(1)在cube目錄下建立rect.go文件,裏面寫rect代碼

// 讓rect結構體在cube包內

package cube


// 定義rect結構體

type rect struct{

        length, width int

}


/**

 * 獲取矩形的面積

 */

func (r Rect) GetArea() int {

        return r.length * r.width

}


/**

 * 獲取矩形的周長

 */

func (r Rect) GetPerimeter() int {

        return (r.length + r.width) * 2

}


(2)在cube目錄下建立cube.go文件,裏面寫cube代碼

// 讓Cube結構體在cube包內

package cube


// 因爲Cube結構體須要對外,因此首字母大寫

type Cube struct {

        Rect           // 這裏經過嵌套結構體實現GO的繼承

        height int

}


/**

 * 獲取立方體的體積

 */

func (c Cube) GetVolume() int {

        return c.Rect.length * c.Rect.width * c.height

}


/**

 * 重寫父類獲取周長方法

 */

func (c Cube) GetPerimeter() int {

        return (c.Rect.length + c.Rect.width + c.height) * 4

}


/**

 * 爲了更象面向對象編程些,這裏定義了一個方法獲取Cube對象

 */

func NewCube(length, width, height int) Cube {

        return Cube{Rect: Rect{length, width}, height: height}

}


(3)在src目錄下建立main.go文件,該文件與cube目錄同級,裏面寫測試代碼

// 讓main()方法的包爲main

package main


import (

       "cube"  // 因爲要用到上面定義的Cube結構體,因此須要引入Cube結構體所屬包

       "fmt"

)


func main() {

        var c cube.Cube = cube.NewCube(10, 20, 30)  // 經過包名調用cube.go定義的對外方法NewCube()

        fmt.Println("面積:", c.GetArea(), ",體積:", c.GetVolume())  // 經過變量c調用相應方法


        fmt.Println("周長:", c.GetPerimeter())

}

執行go run main.go,獲得執行結果:

wKiom1WpuiywwgvAAABG6TF_56Q376.jpg

       從運行結果能夠看到,儘管Cube沒有定義GetArea()方法,但經過c.GetArea()的確調用到了同時並打印出結果;因爲Cube重寫了GetPerimeter()方法,從結果來看c.GetPerimeter()執行的是Cube的GetPerimeter()就去。

       從該例也不難看出GO的繼承性是經過結構的嵌套來實現的


三、多態性

多態意味着一個對象有多重特徵,在特定的狀況下表現不一樣的狀態,即對應着不一樣的方法

wKiom1Wp5cjDZPmhAACjxTnjA4U819.jpg

Mp3和Iphone都實現了USB接口,並分別實現接口USB定義的方法,當面向對象如此調用時:

USB u1 = new Mp3();

u1.connect();    // 打印出「mp3」


USB u2 = new Iphone();

u2.connect();    // 打印出「iphone」

一樣的接口(USB)對象(u1, u2),因爲實現類不一樣,調用相同的方法(connect()),最終的效果是不一樣的,這就是多態的做用,通常用於「控制反轉」。


那麼Go呢?

Go能夠經過Interface、struct模擬實現多態

在src下建立usb目錄,在usb目錄下建立usb.go文件,裏面定義USB接口

// 把接口USB放在usb包中

package usb


// 定義USB接口,裏面只有一個Connect()方法

type USB interface {

        Connect()

}


在usb目錄下建立mp3.go文件,裏面定義Mp3結構體,併爲該結構體增長Connect(),這樣就至關於實現了接口USB

// 把Mp3結構體放在usb包中

package usb


import (

        "fmt"

)


// 定義Mp3空結構體

type Mp3 struct {

}


// 爲Mp3增長Connect()方法,這樣就缺省實現了USB接口

func (m Mp3) Connect() {

        fmt.Println("mp3")

}


一樣,在usb目錄下建立iphone.go文件,裏面定義Iphone結構體

// 把Iphone結構體放在usb包中

package usb


import (

      "fmt"

)


// 定義Iphone空結構體

type Iphone struct {

}


// 爲Iphone增長Connect()方法,這樣就缺省實現了USB接口

func (i Iphone) Connect() {

        fmt.Println("iphone")

}


下面演示GO語言的多態性:

在src目錄下建立main.go文件,該文件與usb目錄同級,裏面寫測試代碼

package main


import (

        "usb"

)


func main() {

        var m usb.USB = usb.Mp3{}

        m.Connect()


        var n usb.USB = usb.Iphone{}

        n.Connect()

}

執行程序,運行結果以下:

wKiom1Wp622zkvO8AAA9r_LrKnA061.jpg



【備註】:

關於本文的演示代碼能夠在本章節源代碼處下載

相關文章
相關標籤/搜索