所謂萬物皆可對象校坑,面向?qū)ο缶幊蹋╫op)是一個很重要的編程思想穷遂,面向?qū)ο蟮暮诵模豪^承函匕、多態(tài);但go跟c++不一樣蚪黑,go沒有c++的class盅惜,也沒有繼承的關(guān)鍵字,但是go依然可以實(shí)現(xiàn)oop忌穿。
以下通過一個簡單例子來展示go語言中的面向?qū)ο蟆?/p>
繼承
go中沒有class抒寂,對于繼承也沒有任何關(guān)鍵字,但是go有type關(guān)鍵字掠剑,并且有struct屈芜,我們可用struct定義自己需要的類型,以下定義了三個struct朴译,并且希望有一個父類Animal井佑,兩個子類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中定義了一個名為Basic的Animal類型,Dog中沒有定義變量類型澜公,這兩種方式都可以姆另,取決于個人習(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語言中的多態(tài)如何實(shí)現(xiàn)迹辐。go為我們提供了一個interface類型,我們可以借助interface來實(shí)現(xiàn)多態(tài)甚侣,如下:
type AnimalSounder interface {
MakeNoise()
}
func MakeSomeNoise(animalSounder AnimalSounder) {
animalSounder.MakeNoise()
}
我們將AnimalSounder定義為一個interface類型明吩,AnimalSounder中包含了一個MakeNoise()函數(shù)。
在上一步中殷费,Dog和Cat都實(shí)現(xiàn)了MakeNoise這個函數(shù)印荔,那么我們就認(rèn)為Dog和Cat都實(shí)現(xiàn)了AnimalSounder這個接口。
此外我們還定義了一個MakeSomeNoise函數(shù)详羡,我們通過MakeSomeNoise實(shí)現(xiàn)了多態(tài)仍律,入?yún)⒕褪墙涌凇=又覀冎恍枰獙at和Dog做初始化实柠,接著將初始化的對象作為參數(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