#### Go 中面向對象的三大特性
上週由於有一些事情,停更了; 停更的這段時間,花了點時間作了一個小項目(https://github.com/yioMe/node_wx_alipay_personalPay)
原項目由node.js 寫的,根據文檔用Go 重寫了(Gin + MySQL) ;
1. 沒有了繁瑣的node安裝;
2. 沒有 DB 遷移;
3. 支付成功回調優化;
4. 性能提高;
5. 修復了上傳二維碼不能識別的問題;
不過只重寫了一小部分功能,應對平常我的支付不成問題,若有須要瞭解的朋友,私聊一同交流學習;
---
言歸正傳,Go 中的面向對象的特性與傳統的OOP 語言不一樣,咱們來一一學習瞭解;
###### 封裝
封裝就是把抽象的字段的對字段的操做封裝在一塊兒,數據被保護在內部,程序中的其它包只能經過被受權的操做才能對
字段操做;
封裝的好處:
1. 隱藏實現的細節;
2. 能夠對數據進行驗證,保證數據的安全合理;
---
封裝實現的步驟:
1. 將結構體,字段的首字母小寫,不能被導出,其它包不能使用,相似JAVA 的private ;
2. 在結構體所在的包提供一下工廠模式的函數,首寫字母大寫,相似構造函數;
3. 提供一個首字母大寫的Set 方法,用於對屬性的判斷並賦值
4. 提供一個首字母大寫的Get 方法,用於獲取屬性的值;
5. 在Go 中沒有特別強調封裝,因此有其它編程語言的朋友,不須要用其它的語法特性來學習Go, 每種編程語言都有各自的特色;
package model import "fmt" type student struct { Name string age int // 其它的包不能直接訪問 score float64 // 其它的包不能直接訪問 } // 工廠方法,至關於構造函數 func NewStudent(name string) *student{ return &student{ Name:name, } } // 爲了訪問和更改結構體的屬性,編寫一對GetXxx/SetXxx 的方法 // this 只是接收類型的名稱, 能夠命名爲任意合法的標識符 func (this *student) GetAge() int { return this.age } func (this *student) SetAge(age int){ // 能夠在Set 方法裏對數據進行校驗 if age < 0 || age > 100 { fmt.Println("age is wrong") return } this.age = age } func (this *student) GetScore() float64{ return this.score } func (this *student) SetScore(score float64) { if score < 0 || score > 100 { fmt.Println("score is wrong") return } this.score = score }
package main import ( "fmt" "personalPayment/model" ) func main(){ p := model.NewStudent("jack") p.SetAge(20) p.SetScore(200) fmt.Println(*p) fmt.Println(p.Name,"age=",p.GetAge(),"score=",p.GetScore()) }
---
###### 繼承
1. 繼承能夠解決代碼的複用問題
2. 當多個結構體有相同的屬性和方法時,能夠從這些結構體中抽象一下基礎的結構體,在該結構體中定義相同的屬性和方法;
3. Go 中實現繼承是經過結構體匿名嵌套來實現;
基本語法:
type Person struct {
Name string
Age int
}
type Student struct {
Person // 嵌套的結構體,實現繼承
Score float64
}
案例:
package model import "fmt" type person struct { Name string age int } type student struct { person score float64 // 其它的包不能直接訪問 } type teacher struct { person class string } // 學生的工廠方法,至關於構造函數 func NewStudent(name string) *student{ return &student{ person:person{ Name:name, }, } } // 老師的工廠方法 func NewTeacher(name string) *teacher{ return &teacher{person:person{ Name:name, }} } // 基礎結構的公衆方法 func (this *person) GetAge() int { return this.age } func (this *person) SetAge(age int){ // 能夠在Set 方法裏對數據進行校驗 if age < 0 || age > 100 { fmt.Println("age is wrong") return } this.age = age } // 學生的方法 func (this *student) GetScore() float64{ return this.score } func (this *student) SetScore(score float64) { if score < 0 || score > 100 { fmt.Println("score is wrong") return } this.score = score } // 老師的方法 func (this *teacher) GetClass() string { return this.class } func (this *teacher) SetClass(class string){ this.class = class }
package main import ( "fmt" "personalPayment/model" ) func main(){ s := model.NewStudent("jack") // 調用公用的結構體方法 s.SetAge(20) // 調用本身的方法 s.SetScore(100) fmt.Println(s.Name,s.GetAge(),s.GetScore()) t := model.NewTeacher("tom") // 調用公用的結構體方法 t.SetAge(40) // 調用本身的方法 t.SetClass("English") fmt.Println(t.Name,t.GetAge(),t.GetClass()) }
繼承的使用和注意事項
1. 結構體可使用嵌套匿名的結構體中的全部的屬性和方法,不論大寫與小寫
2. 結構體中匿名結構體的字段和方法能夠簡化;
3. 當結構體和匿名結構體有相同的屬性和方法時,編譯器採用就近原則,若是須要訪問匿名結構體中的字段
和方法須要經過匿名結構體的名稱來區分;
4. 若是一個結構體嵌套了一個有名稱的結構體,這種模式稱爲組合,在訪問組合的結構體或方法時須要加上結構體的名字;
package main import ( "fmt" ) type person struct { Name string Age int skill string } type student struct { person score float64 } func (p *person) Say(){ fmt.Println("I am a person") } func (p *person) Do(){ fmt.Println("I am doing something") } type A struct { Name string } type B struct { A Name string } type C struct { Name string } type D struct { c C Age int } func main(){ s := &student{} s.person.Say() s.person.Do() s.person.Name = "jack" s.person.Age = 20 s.person.skill = "speak" fmt.Println(*s) // 對匿名結構體中的屬性方法能夠簡化爲 s.Say() s.Do() s.Name = "jack2" s.Age = 21 s.skill = "laugh" fmt.Println(*s) // 若是結構體和匿名結構體中有相同的屬性或方法,編譯器將採用就近原則, // 若是須要訪問匿名結構體的屬性和方法須要經過匿名結構體的名稱 a := B{ A: A{ Name:"aaa", }, Name:"bbb", } fmt.Println(a.Name) // bbb fmt.Println(a.A.Name) // aaa // 對於組合,在訪問繼承結構體的方法或屬性時須要加上結構體的名稱 d := D{ c:C{Name:"ccc"}, Age:20, } fmt.Println(d.Age) // 本身的屬性 fmt.Println(d.c.Name) // 訪問繼承的屬性 }
我的微信公衆號上有最新文章,歡迎關注一同交流學習node