Golang中雖然沒有class,但是通過結構體struct依然支持OOP(封裝、多態、繼承)。
Struct
使用struct封裝對象的屬性。
type Person struct {
// 大寫、公有
Name string
Age int
}
Golang同樣支持繼承,不需要extends,只需要在struct中添加父類屬性即可。
type Student struct {
// 繼承自Person類
p Person
ID string
}
Golang的多態一樣很簡單,只要實現了接口的方法同名方法,就是實現了接口。
type Human interface {
speak(language string)
}
type Chinese struct {
}
type American struct {
}
func (chinese Chinese) speak(language string){
fmt.Println("中國人說中國話")
}
func (american American) speak(language string){
fmt.Println("American speak english")
}
值拷貝
struct結構體變量是值類型,而非其他語言中的引用類型。例:
type Person struct {
Name string
Age int
}
func (p Person) ChangeName() {
p.Name = "李四"
fmt.Println("ChangeName():"+p.Name)
}
func main() {
// 結構體是值類型
p := Person{"張三",99}
fmt.Println("1 : main():"+p.Name)
p.ChangeName()
fmt.Println("2 : main():"+p.Name)
}
輸出結果:
1 : main():張三
ChangeName():李四
2 : main():張三
如果需要在方法中修改值類型屬性的值,則要通過指針(引用變量則可以直接修改)
例如:
func (p *Person) ChangeName() {
p.Name = "李四"
fmt.Println("ChangeName():"+p.Name)
}
此時的輸出結果爲:
1 : main():張三
ChangeName():李四
2 : main():李四
通過指針,方法中的修改生效了。
引用類型
如果struct中定義了引用變量的屬性,則要切記在初始化前調用需要make
type Person struct {
Name string
Age int
score []int
}
func main(){
var p Person
// p.Score = []int{1,2,4,5,6}
// p.Score = make([]int,10)
fmt.Println(p.Score[0])
}
panic: runtime error: index out of range
值拷貝:
結構體是值類型,默認是值拷貝
p := Person{"張三",99,[]int{1,2,3,4,5}}
p2 := p
fmt.Println(p)
p2.Name = "王五"
fmt.Println(p)
// 修改p2不會影響到p
fmt.Println(p2)
這種方式修改p2不會影響到p
p := Person{"張三",99,[]int{1,2,3,4,5}}
p2 := &p
fmt.Println(p)
p2.Name = "王五"
fmt.Println(p)
// 修改p2會影響到p
fmt.Println(*p2)