所謂萬(wàn)物皆可對(duì)象,面向?qū)ο缶幊蹋╫op)是一個(gè)很重要的編程思想,面向?qū)ο蟮暮诵模豪^承、多態(tài);但go跟c++不一樣,go沒(méi)有c++的class,也沒(méi)有繼承的關(guān)鍵字,但是go依然可以實(shí)現(xiàn)oop。
以下通過(guò)一個(gè)簡(jiǎn)單例子來(lái)展示go語(yǔ)言中的面向?qū)ο蟆?/p>
繼承
go中沒(méi)有class,對(duì)于繼承也沒(méi)有任何關(guān)鍵字,但是go有type關(guān)鍵字,并且有struct,我們可用struct定義自己需要的類型,以下定義了三個(gè)struct,并且希望有一個(gè)父類Animal,兩個(gè)子類Cat和Dog,如下:
type Animal struct {
Name string
mean bool
}
type Cat struct {
Basics Animal
MeowStrength int
}
type Dog struct {
Animal
BarkStrength int
}
在Cat和Dog中,都定義了Animal類型,Cat中定義了一個(gè)名為Basic的Animal類型,Dog中沒(méi)有定義變量類型,這兩種方式都可以,取決于個(gè)人習(xí)慣。
接著我們可以為各自的類實(shí)現(xiàn)他們的函數(shù):
func (dog *Dog) MakeNoise() {
barkStrength := dog.BarkStrength
if dog.mean == true {
barkStrength = barkStrength * 5
}
for bark := 0; bark < barkStrength; bark++ {
fmt.Printf("BARK ")
}
fmt.Println("")
}
func (cat *Cat) MakeNoise() {
meowStrength := cat.MeowStrength
if cat.Basics.mean == true {
meowStrength = meowStrength * 5
}
for meow := 0; meow < meowStrength; meow++ {
fmt.Printf("MEOW ")
}
fmt.Println("")
}
多態(tài)
繼承搞定了,我們看下go語(yǔ)言中的多態(tài)如何實(shí)現(xiàn)。go為我們提供了一個(gè)interface類型,我們可以借助interface來(lái)實(shí)現(xiàn)多態(tài),如下:
type AnimalSounder interface {
MakeNoise()
}
func MakeSomeNoise(animalSounder AnimalSounder) {
animalSounder.MakeNoise()
}
我們將AnimalSounder定義為一個(gè)interface類型,AnimalSounder中包含了一個(gè)MakeNoise()函數(shù)。
在上一步中,Dog和Cat都實(shí)現(xiàn)了MakeNoise這個(gè)函數(shù),那么我們就認(rèn)為Dog和Cat都實(shí)現(xiàn)了AnimalSounder這個(gè)接口。
此外我們還定義了一個(gè)MakeSomeNoise函數(shù),我們通過(guò)MakeSomeNoise實(shí)現(xiàn)了多態(tài),入?yún)⒕褪墙涌凇=又覀冎恍枰獙?duì)Cat和Dog做初始化,接著將初始化的對(duì)象作為參數(shù)傳入MakeSomeNoise,即可實(shí)現(xiàn)多態(tài),聲明如下:
func main() {
myDog := &Dog{
Animal{
"Rover", // Name
false, // mean
},
2, // BarkStrength
}
myCat := &Cat{
Basics: Animal{
Name: "Julius",
mean: true,
},
MeowStrength: 3,
}
MakeSomeNoise(myDog)
MakeSomeNoise(myCat)
}
完整代碼:
package main
import (
"fmt"
)
type Animal struct {
Name string
mean bool
}
type AnimalSounder interface {
MakeNoise()
}
type Dog struct {
Animal
BarkStrength int
}
type Cat struct {
Basics Animal
MeowStrength int
}
func main() {
myDog := &Dog{
Animal{
"Rover", // Name
false, // mean
},
2, // BarkStrength
}
myCat := &Cat{
Basics: Animal{
Name: "Julius",
mean: true,
},
MeowStrength: 3,
}
MakeSomeNoise(myDog)
MakeSomeNoise(myCat)
}
func (dog *Dog) MakeNoise() {
barkStrength := dog.BarkStrength
if dog.mean == true {
barkStrength = barkStrength * 5
}
for bark := 0; bark < barkStrength; bark++ {
fmt.Printf("BARK ")
}
fmt.Println("")
}
func (cat *Cat) MakeNoise() {
meowStrength := cat.MeowStrength
if cat.Basics.mean == true {
meowStrength = meowStrength * 5
}
for meow := 0; meow < meowStrength; meow++ {
fmt.Printf("MEOW ")
}
fmt.Println("")
}
func MakeSomeNoise(animalSounder AnimalSounder) {
animalSounder.MakeNoise()
}
參考:
https://www.ardanlabs.com/blog/2013/07/object-oriented-programming-in-go.html