go語言面向編程

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

物件導向編程篇
go語言物件導向編程,並不像傳統物件導向編程中有繼承、封裝、多態、函數重載等概念;
go語言物件導向編程非常的 簡單優雅,,結構(struct)、方法(method)、介面(interface)
渾然一體,共同支援著 物件導向編程

一、結構體 struct
go語言支援基本類型組合功能-struct結構類型,struct結構類型看似簡單,實則能實現很強大的複雜功能
1. 定義
type <name> struct {}

type Rect struct {
x, y float64
width, height float64
}
2. 初始化
2.1 初始化可以有多種方式:
rect1 := new(Rect)//返回一個指向類型的指標
rect2 := &Rect{}//初始化為一個空的結構類型
rect3 := &Rect{1, 1, 2, 2}//按順序進隱式初始化
rect4 := &Rect{width:2, height:2}//顯示初始化

ps: 1)對結構初始化的時候,建議對結構取地址符號,主要原因是struct類型是值傳遞,在其它函數方法內修改struct,並不會影響struct;
2)未進行顯式初始化的變數都會被初始化為該類型的零值

2.2 對象的建立也可使用一個 全域的建立函數來完成,表示“建構函式”, 一般命名為 NewXXX
func NewXXX(x, y, width, height float64) *Rect {
return &Rect{x, y, width, height}
}

3. 匿名結構
3.1 匿名結構就是 只有類型沒有名稱的結構
3.2 定義及初始化
3.2.1 直接定義及初始化
a := &struct {
name string
age int
}{
name: "xuww",
age: 20,
}
3.2.2 以嵌入結構形式
type X struct {
Name string
}
type Y struct {
X//以X類型作為欄位名
Age int
}
s := &Y {X:X{"xuww"}, Age:20}
3.2.3 以嵌入匿名結構形式
type Y struct {
X struct {
Name string
}
Age int
}

4. 匿名欄位
4.1 匿名欄位就是 只有類型沒有名稱的欄位
匿名欄位 本質上是 定義了以某個類型作為名稱 的欄位

5. 嵌入結構
雖然go語言中,沒有繼承和多態, 但是通過嵌入結構,可以實作類別似功能
type Base struct {
Name string
}
func (b *Base) Foo() {
fmt.Println(b.Name, "from Base Foo()")
}
func (b *Base) Bar() {
fmt.Println(b.Name, "from Base Bar()")
}

type Sub struct {
Base //"繼承" Base 所有屬性
Age int
}
func (s *Sub) Bar() { //在Sub方法中,重寫Bar()函數,"多態"
s.Name = "Hello"
fmt.Println(s.Name, "from Sub Bar()")
}

6. 同名欄位
同一層級,不能出現同名欄位
不同層級,可以出現同名欄位
type A struct {
B// 結構體A中name層級要高於結構體B中name層級, 所以可同名
//C// B C 結構體中 name 是同一層級,同名欄位會出錯
name string
}

type B struct {
name string
}

type C struct {
name string
}

低層級的同名欄位被隱藏,使用時需要顯示調用
類似: a.B.Name

7. 反引號
在結構體的型別宣告的欄位後面我們可以添加一個由反引號“`”括起來的標籤,供reflect使用:


二、方法
go語言物件導向編程非常簡潔直觀,通過對 方法施加的目標(對象)顯示傳遞,可以很清晰的看到是 誰的方法,
不像c++在物件導向編程時,會隱藏this指標。

1. 方法概述
1.1 方法和函數類似,只是多了receiver,編譯器就是根據receiver,來判斷是誰的方法
1.2 go語言中,不存在方法重載
1.3 receiver也是遵循正常的參數規則,如果是以 實值型別傳遞,只能得到對象的一個拷貝(副本),
所以說如果需要修改對象的時候, 必須用 指標傳遞

1.4 在go語言中,可以給任意類型(包括內建類型,但不包括指標類型)添加相應的方法,

2. Method Value 與 Method Expresion
Method Value
已經聲明了receiver,用變數或對象 來調用函數一樣 調用方法
Method Expression
通過類型去調用方法, 把變數或對象 作為receiver,並作為第一個參數 傳遞給方法

type IT int
func (it *IT) Print() {
fmt.Println("IT Method")
}

var a IT
a.Print() //Method Value
(*IT).Print(&a) //Method Expression

3. 方法名稱衝突
嵌入結構有 欄位名稱衝突, 方法也有 名稱衝突,

處理的原則同欄位名稱衝突類似,即:
如果外部結構和嵌入結構存在同名方法,則優先調用外部結構的方法;
如果同一對象 有同名方法(receiver + 函數名),編譯會報錯

三、介面
在其它物件導向程式設計語言中, 實作類別需要明確聲明自己實現了哪個介面,這種強制性不利於開發,
但是在go語言中,只要某個類型實現了 該介面的所有方法,即算實現該介面,無需顯示聲明實現了哪個介面,這稱為 Structural Typing

1. 介面定義
介面是一個或多個方法簽名的集合,介面只有方法聲明,沒有實現,沒有資料欄位
type USB interface {
Phone() string
Connect()
}

2. 介面賦值
介面賦值分為兩種情況:
將對象執行個體賦值給介面
將一個介面賦值給另一個介面
2.1 將對象賦值給介面
type A interface {....}
type B struct {
Name string
}
//假設B類型實現了A介面
var a A = B{"hi"}
或者 var a A = &B{"hi"}

ps:將對象賦值給介面時,會發生拷貝,而介面內部儲存的黑絲指向之歌複製品的指標,

2.2 將一個介面賦值給另外一個介面
只要兩個介面擁有相同的方法列表(次序不同不要緊),那麼他們就是等同的,可以相互賦值;
可以將擁有超集介面 轉換為 子集介面

3. 嵌入介面(有點像 繼承)
介面可以匿名嵌入到其它介面中
type USB interface {
Phone() string
CONNECT //匿名介面嵌入
}

type CONNECT interface {
Connect()
}

4. 介面查詢
查詢某一介面 指向的對象執行個體 是否實現了 另外一介面
查詢某一介面 指向的對象執行個體 是否是 某一類型

介面查詢使用的是 ok-pattern模式來判斷

type A interface {
Read()
Write()
}

type B interface {
Read()
}

type File struct {
Name string
}

func (f *File) Read() {
fmt.Println(f.Name, "Read")
}

func (f *File) Write() {
fmt.Println(f.Name, "Write")
}

var a A = &File{"Hi"}
var b B

if v, ok := a.(B); ok { //查詢a介面指向的對象執行個體 是否實現了 B介面
fmt.Println("a has implement B interface")
b = v
}

if _, ok := a.(*File); ok { //查詢a介面指向的對象執行個體 是否是 *File類型
fmt.Println("*File has implement A interface")
}

5. 類型查詢
在go語言中,可以直截了當詢問 介面 指向的對象執行個體 的類型
使用 switch-case模式來判斷
例如:
var v1 interface{} = ...
switch v := v1.(type) {
case int://判斷類型
...// v就是 v1的值
case string:
default:
...
}

ps: 空介面 常常配合 type-switch使用

6. Any類型 --- 空介面
go語言中,空介面 非常有用
因為是空介面,所以任意類型都實現了空介面 interface{},
所以說 interface{} 是 Any類型

變數類型
函數參數類型
傳回值類型

使用空介面使得程式有更大的擴充性

空介面通常結合 type-switch使用

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.