一文詳解Go的面向?qū)ο缶幊?/h1>
更新時間:2023年04月27日 09:29:56 作者:Pokeya
本文主要圍繞 Golang 的 Object-oriented 所展開,介紹了其基本的面向?qū)ο蟮幕靖拍罴按a實戰(zhàn),有需要的小伙伴跟著小編一起來學(xué)習(xí)吧
概述
Go
語言的面向?qū)ο缶幊逃腥齻€重要的思想:封裝、繼承和多態(tài)。
- 封裝
Go
語言通過 struct
結(jié)構(gòu)體的方式來實現(xiàn)封裝,結(jié)構(gòu)體可以包含各種類型的變量和方法,可以將一組相關(guān)的變量和方法封裝在一起。使用首字母大小寫控制變量和方法的訪問權(quán)限,實現(xiàn)了信息隱藏和訪問控制。
- 繼承
Go
語言中沒有傳統(tǒng)的繼承機制,但是可以使用嵌入式類型來實現(xiàn)類似繼承的效果,將一個類型嵌入到另一個類型中,從而繼承嵌入類型的方法和屬性。嵌入式類型的特點是可以直接訪問嵌入類型的屬性和方法,不需要通過接口或者其他方式進行轉(zhuǎn)換。在 Go
語言中,可以通過 struct
嵌套和 interface
嵌套來實現(xiàn)繼承的效果。
- 多態(tài)
Go
語言通過接口來實現(xiàn)多態(tài),一個類型只需要實現(xiàn)了接口的所有方法,就可以被賦值給該接口類型的變量。這樣可以實現(xiàn)類似于面向?qū)ο笳Z言中的多態(tài)性。多態(tài)性使得程序可以根據(jù)上下文環(huán)境自動選擇合適的方法實現(xiàn),提高了代碼的靈活性和可復(fù)用性。
實戰(zhàn)
常規(guī)函數(shù)寫法
在這個示例中,函數(shù)和結(jié)構(gòu)體是分離的,函數(shù)接收結(jié)構(gòu)體指針類型作為參數(shù),需要手動傳遞結(jié)構(gòu)體的指針。盡管這種方式有一定的缺陷,調(diào)用會比較麻煩,但它更加符合基于過程式編程思想的設(shè)計理念,即將一個大問題拆分成多個小問題,并通過函數(shù)解決這些小問題。適用于初學(xué)者對于代碼的簡單操作。優(yōu)點就只有易于理解。
package test
import (
"fmt"
"testing"
)
type Mobile struct {
User string `json:"user"`
Brand string `json:"brand"`
Prise float64 `json:"prise"`
}
func CallUp(m *Mobile) {
fmt.Printf("%s is using ??%.2f mobile phone to make a call.\n", m.User, m.Prise)
}
func Storage(m *Mobile) {
fmt.Printf("%s is using a %s mobile phone to transfer data.\n", m.User, m.Brand)
}
func Charge(m *Mobile) string {
return fmt.Sprintf("%s is charging a %s phone.\n", m.User, m.Brand)
}
func Game(m *Mobile, name string) {
fmt.Printf("%s is playing the game of '%s'.\n", m.User, name)
}
func TestExample(t *testing.T) {
iPhone := Mobile{
User: "Tom",
Brand: "iPhone 15 Pro MAX",
Prise: 12688.00,
}
CallUp(&iPhone)
Game(&iPhone, "Card")
Storage(&iPhone)
fmt.Printf(Charge(&iPhone))
}
調(diào)用結(jié)構(gòu)體類型上的方法
調(diào)用結(jié)構(gòu)體類型上的方法體現(xiàn)了面向?qū)ο缶幊痰姆庋b思想。封裝的核心是將數(shù)據(jù)和行為打包在一起,通過公開和私有的方式來隱藏實現(xiàn)細(xì)節(jié)。這樣可以使得代碼更加模塊化、安全、易于維護,并且更加符合現(xiàn)實世界中的抽象模型。
相比于上面的函數(shù)調(diào)用,調(diào)用結(jié)構(gòu)體類型上的方法可以使調(diào)用方法時不必手動傳遞結(jié)構(gòu)體實例對象,只需聚焦于方法參數(shù)本身,提高了代碼的可讀性和易用性。這也符合面向?qū)ο缶幊痰暮啙嵭院痛a重用性的思想。
?? 提示:在代碼注釋中類比了 Python
中類的寫法。
package test
import (
"fmt"
"testing"
)
// class Mobile(object)
type Mobile struct {
User string `json:"user"`
Brand string `json:"brand"`
Prise float64 `json:"prise"`
}
// def __init__(user, brand, prise)
func NewMobile(user string, brand string, prise float64) *Mobile {
return &Mobile{User: user, Brand: brand, Prise: prise}
}
// def call_up(self)
func (m *Mobile) CallUp() {
fmt.Printf("%s is using ??%.2f mobile phone to make a call.\n", m.User, m.Prise)
}
// def storage(self)
func (m *Mobile) Storage() {
fmt.Printf("%s is using a %s mobile phone to transfer data.\n", m.User, m.Brand)
}
// def charge(self)
func (m *Mobile) Charge() string {
return fmt.Sprintf("%s is charging a %s phone.\n", m.User, m.Brand)
}
// def game(self, name)
func (m *Mobile) Game(name string) {
fmt.Printf("%s is playing the game of '%s'.\n", m.User, name)
}
func TestExample(t *testing.T) {
applePhone := NewMobile("Tom", "iPhone 15 Pro MAX", 12688.00)
applePhone.CallUp()
applePhone.Game("Card")
applePhone.Storage()
fmt.Printf(applePhone.Charge())
}
調(diào)用接口類型上的方法
接口實例: 是指定義一個接口類型,并將具體的結(jié)構(gòu)體類型的實例傳遞給它。
調(diào)用接口類型上的方法,將接口與結(jié)構(gòu)體類型分開,使接口具有更廣泛的適用性。使用 “接口實例” 可以實現(xiàn)更靈活的代碼設(shè)計,因為可以在運行時動態(tài)地選擇要使用的實現(xiàn)類型。
同時,由于接口只關(guān)心方法的簽名,而不關(guān)心具體實現(xiàn)方式,因此可以將不同的結(jié)構(gòu)體類型傳遞給同一個接口,從而實現(xiàn)面向?qū)ο笏枷氲亩鄳B(tài)性。
在這個示例中,定義了一個 USB
接口和 PlayBoy
接口,它們都包含各自的方法。在測試函數(shù)中調(diào)用這兩個接口的方法時需要分別調(diào)用。這兩個接口之間沒有直接的聯(lián)系或關(guān)聯(lián),它們是相互獨立的。如果你想將這兩個接口組合在一起,可以使用 “嵌入式接口”。
package test
import (
"fmt"
"testing"
)
var (
applePhone, huaweiPhone *Mobile
)
func init() {
applePhone = NewMobile("Tom", "iPhone 15 Pro MAX", 12688.00)
huaweiPhone = NewMobile("John", "Huawei Meta 40 Pro", 8888.00)
}
type USB interface {
Storage()
Charge() string
}
type PlayBoy interface {
Game(name string)
}
type Mobile struct {
User string `json:"user"`
Brand string `json:"brand"`
Prise float64 `json:"prise"`
}
func NewMobile(user string, brand string, prise float64) *Mobile {
return &Mobile{User: user, Brand: brand, Prise: prise}
}
func (m *Mobile) CallUp() {
fmt.Printf("%s is using ??%.2f mobile phone to make a call.\n", m.User, m.Prise)
}
func (m *Mobile) Storage() {
fmt.Printf("%s is using a %s mobile phone to transfer data.\n", m.User, m.Brand)
}
func (m *Mobile) Charge() string {
return fmt.Sprintf("%s is charging a %s phone.\n", m.User, m.Brand)
}
func (m *Mobile) Game(name string) {
fmt.Printf("%s is playing the game of '%s'.\n", m.User, name)
}
func TestExample(t *testing.T) {
USB.Storage(applePhone)
fmt.Printf(USB.Charge(huaweiPhone))
PlayBoy.Game(huaweiPhone, "LOL")
}
嵌入式接口
嵌入式接口: 是一種將一個接口嵌入到另一個接口中的技術(shù),嵌入的接口中的所有方法都會被繼承到當(dāng)前接口中。通過接口的嵌套,可以將多個接口組合成一個更大的接口,從而使代碼更加簡潔、靈活。這也體現(xiàn)了面向?qū)ο缶幊讨械睦^承特性。
在這個示例中,定義了一個 IPhone
接口,它嵌入了 USB
接口和 PlayBoy
接口,以及 CallUp()
方法。 從而可以使用這三個接口中的所有方法。通過這種方式,我們可以將不同的接口組合成一個更大的接口,以便更方便地使用這些方法。在測試函數(shù)中,我們創(chuàng)建了一個 Mobile
類型的實例,并將其轉(zhuǎn)換為 IPhone
類型的接口實例 p
,然后可以使用 p
調(diào)用 Mobile
結(jié)構(gòu)體中實現(xiàn)的 CallUp()
、Game()
、Storage()
和 Charge()
方法。
package test
import (
"fmt"
"testing"
)
type IPhone interface {
USB
PlayBoy
CallUp()
}
type USB interface {
Storage()
Charge() string
}
type PlayBoy interface {
Game(name string)
}
type Mobile struct {
User string `json:"user"`
Brand string `json:"brand"`
Prise float64 `json:"prise"`
}
func (m *Mobile) CallUp() {
fmt.Printf("%s is using ??%.2f mobile phone to make a call.\n", m.User, m.Prise)
}
func (m *Mobile) Storage() {
fmt.Printf("%s is using a %s mobile phone to transfer data.\n", m.User, m.Brand)
}
func (m *Mobile) Charge() string {
return fmt.Sprintf("%s is charging a %s phone.\n", m.User, m.Brand)
}
func (m *Mobile) Game(name string) {
fmt.Printf("%s is playing the game of '%s'.\n", m.User, name)
}
func TestExample(t *testing.T) {
newMobile := &Mobile{User: "John", Brand: "Huawei Meta 40 Pro", Prise: 8888.00}
var p IPhone = newMobile
p.CallUp()
p.Game("Card")
p.Storage()
fmt.Printf(p.Charge())
}
到此這篇關(guān)于一文詳解Go的面向?qū)ο缶幊痰奈恼戮徒榻B到這了,更多相關(guān)Go面向?qū)ο髢?nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
-
Go語言中比較兩個map[string]interface{}是否相等
本文主要介紹了Go語言中比較兩個map[string]interface{}是否相等,我們可以將其轉(zhuǎn)化成順序一樣的 slice ,然后再轉(zhuǎn)化未json,具有一定的參考價值,感興趣的可以了解一下 2023-08-08
-
Go?interface?接口的最佳實踐經(jīng)驗分享
go?的接口在go的編程里面用的十分頻繁,尤其是空接口的使用,因為有了接口,才使得Go語言變得異常的強大,今天給大家介紹下Go?interface?接口的最佳實踐經(jīng)驗分享,感興趣的朋友一起看看吧 2022-04-04
-
Go語言使用goroutine及通道實現(xiàn)并發(fā)詳解
這篇文章主要為大家介紹了Go語言使用goroutine及通道實現(xiàn)并發(fā)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪 2022-08-08
-
Go語言正則表達(dá)式用法實例小結(jié)【查找、匹配、替換等】
這篇文章主要介紹了Go語言正則表達(dá)式用法,結(jié)合實例形式分析了Go語言基于正則實現(xiàn)查找、匹配、替換等基本操作的實現(xiàn)技巧,需要的朋友可以參考下 2017-01-01
最新評論
概述
Go
語言的面向?qū)ο缶幊逃腥齻€重要的思想:封裝、繼承和多態(tài)。
- 封裝
Go
語言通過 struct
結(jié)構(gòu)體的方式來實現(xiàn)封裝,結(jié)構(gòu)體可以包含各種類型的變量和方法,可以將一組相關(guān)的變量和方法封裝在一起。使用首字母大小寫控制變量和方法的訪問權(quán)限,實現(xiàn)了信息隱藏和訪問控制。
- 繼承
Go
語言中沒有傳統(tǒng)的繼承機制,但是可以使用嵌入式類型來實現(xiàn)類似繼承的效果,將一個類型嵌入到另一個類型中,從而繼承嵌入類型的方法和屬性。嵌入式類型的特點是可以直接訪問嵌入類型的屬性和方法,不需要通過接口或者其他方式進行轉(zhuǎn)換。在 Go
語言中,可以通過 struct
嵌套和 interface
嵌套來實現(xiàn)繼承的效果。
- 多態(tài)
Go
語言通過接口來實現(xiàn)多態(tài),一個類型只需要實現(xiàn)了接口的所有方法,就可以被賦值給該接口類型的變量。這樣可以實現(xiàn)類似于面向?qū)ο笳Z言中的多態(tài)性。多態(tài)性使得程序可以根據(jù)上下文環(huán)境自動選擇合適的方法實現(xiàn),提高了代碼的靈活性和可復(fù)用性。
實戰(zhàn)
常規(guī)函數(shù)寫法
在這個示例中,函數(shù)和結(jié)構(gòu)體是分離的,函數(shù)接收結(jié)構(gòu)體指針類型作為參數(shù),需要手動傳遞結(jié)構(gòu)體的指針。盡管這種方式有一定的缺陷,調(diào)用會比較麻煩,但它更加符合基于過程式編程思想的設(shè)計理念,即將一個大問題拆分成多個小問題,并通過函數(shù)解決這些小問題。適用于初學(xué)者對于代碼的簡單操作。優(yōu)點就只有易于理解。
package test import ( "fmt" "testing" ) type Mobile struct { User string `json:"user"` Brand string `json:"brand"` Prise float64 `json:"prise"` } func CallUp(m *Mobile) { fmt.Printf("%s is using ??%.2f mobile phone to make a call.\n", m.User, m.Prise) } func Storage(m *Mobile) { fmt.Printf("%s is using a %s mobile phone to transfer data.\n", m.User, m.Brand) } func Charge(m *Mobile) string { return fmt.Sprintf("%s is charging a %s phone.\n", m.User, m.Brand) } func Game(m *Mobile, name string) { fmt.Printf("%s is playing the game of '%s'.\n", m.User, name) } func TestExample(t *testing.T) { iPhone := Mobile{ User: "Tom", Brand: "iPhone 15 Pro MAX", Prise: 12688.00, } CallUp(&iPhone) Game(&iPhone, "Card") Storage(&iPhone) fmt.Printf(Charge(&iPhone)) }
調(diào)用結(jié)構(gòu)體類型上的方法
調(diào)用結(jié)構(gòu)體類型上的方法體現(xiàn)了面向?qū)ο缶幊痰姆庋b思想。封裝的核心是將數(shù)據(jù)和行為打包在一起,通過公開和私有的方式來隱藏實現(xiàn)細(xì)節(jié)。這樣可以使得代碼更加模塊化、安全、易于維護,并且更加符合現(xiàn)實世界中的抽象模型。
相比于上面的函數(shù)調(diào)用,調(diào)用結(jié)構(gòu)體類型上的方法可以使調(diào)用方法時不必手動傳遞結(jié)構(gòu)體實例對象,只需聚焦于方法參數(shù)本身,提高了代碼的可讀性和易用性。這也符合面向?qū)ο缶幊痰暮啙嵭院痛a重用性的思想。
?? 提示:在代碼注釋中類比了 Python
中類的寫法。
package test import ( "fmt" "testing" ) // class Mobile(object) type Mobile struct { User string `json:"user"` Brand string `json:"brand"` Prise float64 `json:"prise"` } // def __init__(user, brand, prise) func NewMobile(user string, brand string, prise float64) *Mobile { return &Mobile{User: user, Brand: brand, Prise: prise} } // def call_up(self) func (m *Mobile) CallUp() { fmt.Printf("%s is using ??%.2f mobile phone to make a call.\n", m.User, m.Prise) } // def storage(self) func (m *Mobile) Storage() { fmt.Printf("%s is using a %s mobile phone to transfer data.\n", m.User, m.Brand) } // def charge(self) func (m *Mobile) Charge() string { return fmt.Sprintf("%s is charging a %s phone.\n", m.User, m.Brand) } // def game(self, name) func (m *Mobile) Game(name string) { fmt.Printf("%s is playing the game of '%s'.\n", m.User, name) } func TestExample(t *testing.T) { applePhone := NewMobile("Tom", "iPhone 15 Pro MAX", 12688.00) applePhone.CallUp() applePhone.Game("Card") applePhone.Storage() fmt.Printf(applePhone.Charge()) }
調(diào)用接口類型上的方法
接口實例: 是指定義一個接口類型,并將具體的結(jié)構(gòu)體類型的實例傳遞給它。
調(diào)用接口類型上的方法,將接口與結(jié)構(gòu)體類型分開,使接口具有更廣泛的適用性。使用 “接口實例” 可以實現(xiàn)更靈活的代碼設(shè)計,因為可以在運行時動態(tài)地選擇要使用的實現(xiàn)類型。
同時,由于接口只關(guān)心方法的簽名,而不關(guān)心具體實現(xiàn)方式,因此可以將不同的結(jié)構(gòu)體類型傳遞給同一個接口,從而實現(xiàn)面向?qū)ο笏枷氲亩鄳B(tài)性。
在這個示例中,定義了一個 USB
接口和 PlayBoy
接口,它們都包含各自的方法。在測試函數(shù)中調(diào)用這兩個接口的方法時需要分別調(diào)用。這兩個接口之間沒有直接的聯(lián)系或關(guān)聯(lián),它們是相互獨立的。如果你想將這兩個接口組合在一起,可以使用 “嵌入式接口”。
package test import ( "fmt" "testing" ) var ( applePhone, huaweiPhone *Mobile ) func init() { applePhone = NewMobile("Tom", "iPhone 15 Pro MAX", 12688.00) huaweiPhone = NewMobile("John", "Huawei Meta 40 Pro", 8888.00) } type USB interface { Storage() Charge() string } type PlayBoy interface { Game(name string) } type Mobile struct { User string `json:"user"` Brand string `json:"brand"` Prise float64 `json:"prise"` } func NewMobile(user string, brand string, prise float64) *Mobile { return &Mobile{User: user, Brand: brand, Prise: prise} } func (m *Mobile) CallUp() { fmt.Printf("%s is using ??%.2f mobile phone to make a call.\n", m.User, m.Prise) } func (m *Mobile) Storage() { fmt.Printf("%s is using a %s mobile phone to transfer data.\n", m.User, m.Brand) } func (m *Mobile) Charge() string { return fmt.Sprintf("%s is charging a %s phone.\n", m.User, m.Brand) } func (m *Mobile) Game(name string) { fmt.Printf("%s is playing the game of '%s'.\n", m.User, name) } func TestExample(t *testing.T) { USB.Storage(applePhone) fmt.Printf(USB.Charge(huaweiPhone)) PlayBoy.Game(huaweiPhone, "LOL") }
嵌入式接口
嵌入式接口: 是一種將一個接口嵌入到另一個接口中的技術(shù),嵌入的接口中的所有方法都會被繼承到當(dāng)前接口中。通過接口的嵌套,可以將多個接口組合成一個更大的接口,從而使代碼更加簡潔、靈活。這也體現(xiàn)了面向?qū)ο缶幊讨械睦^承特性。
在這個示例中,定義了一個 IPhone
接口,它嵌入了 USB
接口和 PlayBoy
接口,以及 CallUp()
方法。 從而可以使用這三個接口中的所有方法。通過這種方式,我們可以將不同的接口組合成一個更大的接口,以便更方便地使用這些方法。在測試函數(shù)中,我們創(chuàng)建了一個 Mobile
類型的實例,并將其轉(zhuǎn)換為 IPhone
類型的接口實例 p
,然后可以使用 p
調(diào)用 Mobile
結(jié)構(gòu)體中實現(xiàn)的 CallUp()
、Game()
、Storage()
和 Charge()
方法。
package test import ( "fmt" "testing" ) type IPhone interface { USB PlayBoy CallUp() } type USB interface { Storage() Charge() string } type PlayBoy interface { Game(name string) } type Mobile struct { User string `json:"user"` Brand string `json:"brand"` Prise float64 `json:"prise"` } func (m *Mobile) CallUp() { fmt.Printf("%s is using ??%.2f mobile phone to make a call.\n", m.User, m.Prise) } func (m *Mobile) Storage() { fmt.Printf("%s is using a %s mobile phone to transfer data.\n", m.User, m.Brand) } func (m *Mobile) Charge() string { return fmt.Sprintf("%s is charging a %s phone.\n", m.User, m.Brand) } func (m *Mobile) Game(name string) { fmt.Printf("%s is playing the game of '%s'.\n", m.User, name) } func TestExample(t *testing.T) { newMobile := &Mobile{User: "John", Brand: "Huawei Meta 40 Pro", Prise: 8888.00} var p IPhone = newMobile p.CallUp() p.Game("Card") p.Storage() fmt.Printf(p.Charge()) }
到此這篇關(guān)于一文詳解Go的面向?qū)ο缶幊痰奈恼戮徒榻B到這了,更多相關(guān)Go面向?qū)ο髢?nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語言中比較兩個map[string]interface{}是否相等
本文主要介紹了Go語言中比較兩個map[string]interface{}是否相等,我們可以將其轉(zhuǎn)化成順序一樣的 slice ,然后再轉(zhuǎn)化未json,具有一定的參考價值,感興趣的可以了解一下2023-08-08Go?interface?接口的最佳實踐經(jīng)驗分享
go?的接口在go的編程里面用的十分頻繁,尤其是空接口的使用,因為有了接口,才使得Go語言變得異常的強大,今天給大家介紹下Go?interface?接口的最佳實踐經(jīng)驗分享,感興趣的朋友一起看看吧2022-04-04Go語言使用goroutine及通道實現(xiàn)并發(fā)詳解
這篇文章主要為大家介紹了Go語言使用goroutine及通道實現(xiàn)并發(fā)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08Go語言正則表達(dá)式用法實例小結(jié)【查找、匹配、替換等】
這篇文章主要介紹了Go語言正則表達(dá)式用法,結(jié)合實例形式分析了Go語言基于正則實現(xiàn)查找、匹配、替換等基本操作的實現(xiàn)技巧,需要的朋友可以參考下2017-01-01