## **面向對象編程三大特性\-封裝**
#### **封裝介紹**
封裝(encapsulation)就是把抽象出的字段和對字段的操作封裝在一起,數據被保護在內部,程序的其它包只有通過被授權的操作(方法),才能對字段進行操作
封裝的理解和好處
1)隱藏實現細節
2)提可以對數據進行驗證,保證安全合理(Age)
#### **封裝的實現步驟**
1)將結構體、字段(屬性)的首字母小寫(不能導出了,其它包不能使用,類似private)
2)給結構體所在包提供一個工廠模式的函數,首字母大寫。類似一個構造函數
3)提供一個首字母大寫的Set方法(類似其它語言的public),用于對屬性判斷并賦值
```
func(var結構體類型名)SetXxx(參數列表)(返回值列表){
//加入數據驗證的業務邏輯
var.字段=參數
}
```
4)提供一個首字母大寫的Get方法(類似其它語言的public),用于獲取屬性的值
```
func(var結構體類型名)GetXxx(){
return var.age;
}
```
特別說明:在Golang開發中并沒有特別強調封裝,這點并不像Java.所以提醒學過java的朋友,
不用總是用java的語法特性來看待Golang,Golang本身對面向對象的特性做了簡化的.
#### **快速入門案例**
請大家看一個程序(person.go),不能隨便查看人的年齡,工資等隱私,并對輸入的年齡進行合理的驗證。設計:model包(person.go)main包(main.go調用Person結構體)
model/person.go


main/main.go

## **面向對象編程三大特性-繼承**
1)字段和方法幾乎相同了相同但是我們卻寫了相同的代碼,代碼復用性不強
2)出現代碼冗余,而且代碼不利于維護,同時也不利于功能的擴展。
3)解決方法-通過繼承方式來解決

也就是說:在Golang中,如果一個struct嵌套了另一個匿名結構體,那么這個結構體可以直接訪問匿名結構體的字段和方法,從而實現了繼承特性。
**嵌套匿名結構體的基本語法**
```
typeGoodsstruct{
Namestring
Priceint
}
typeBookstruct{
Goods//這里就是嵌套匿名結構體Goods
Writerstring
}
```
**繼承給編程帶來的便利**
1)代碼的復用性提高了
2)代碼的擴展性和維護性提高了
**繼承的深入討論**
1)結構體可以使用嵌套匿名結構體所有的字段和方法,即:首字母大寫或者小寫的字段、方法,都可以使用。【舉例說明】

2)匿名結構體字段訪問可以簡化,如圖

對上面的代碼小結
(1)當我們直接通過b訪問字段或方法時,其執行流程如下比如b.Name
(2)編譯器會先看b對應的類型有沒有Name,如果有,則直接調用B類型的Name字段
(3)如果沒有就去看B中嵌入的匿名結構體A有沒有聲明Name字段,如果有就調用,如果沒有繼續查找..如果都找不到就報錯.
3)當結構體和匿名結構體有相同的字段或者方法時,編譯器采用就近訪問原則訪問,如希望訪問匿名結構體的字段和方法,可以通過匿名結構體名來區分【舉例說明】

4)結構體嵌入兩個(或多個)匿名結構體,如兩個匿名結構體有相同的字段和方法(同時結構體本身沒有同名的字段和方法),在訪問時,就必須明確指定匿名結構體名字,否則編譯報錯。【舉例說明】

5)如果一個struct嵌套了一個有名結構體,這種模式就是組合,如果是組合關系,那么在訪問組合的結構體的字段或方法時,必須帶上結構體的名字

6)嵌套匿名結構體后,也可以在創建結構體變量(實例)時,直接指定各個匿名結構體字段的值

**結構體的匿名字段是基本數據類型,如何訪問,下面代碼輸出什么**

說明
1)如果一個結構體有int類型的匿名字段,就不能第二個。
2)如果需要有多個int的字段,則必須給int字段指定名字
### **多重繼承說明**
如一個struct嵌套了多個匿名結構體,那么該結構體可以直接訪問嵌套的匿名結構體的字段和方法,從而實現了多重繼承。

**多重繼承細節說明**
1)如嵌入的匿名結構體有相同的字段名或者方法名,則在訪問時,需要通過匿名結構體類型名來區分。【案例演示】

2)為了保證代碼的簡潔性,建議大家盡量不使用多重繼承