golang實現面向物件的封裝、繼承、多型
阿新 • • 發佈:2021-06-28
1. 基本介紹
面向物件程式設計(Object Oriented Programming,OOP)是一種計算機程式設計框架,儘可能的模擬人類的思維方式,使得軟體的開發方法與過程儘可能接近人類認識世界、解決現實問題的方法和過程。
封裝、繼承、多型和抽象是面向物件的4個基本特徵。
2. golang的面向物件型別
- golang實現面向物件的兩個關鍵型別是struct 和interface,struct類似於C++的普通類型別,interface則對應抽象類型別。
- 同時與其他語言採用public、private、protected指示成員和方法的可見性不同,golang採用首字母大小寫來標識成員/方法的可見性,小寫字母開頭表示私有成員,大寫字母開頭表示對外可見。
1、封裝
- 基本介紹:封裝就是把抽象出的欄位和欄位的操作封裝在一起,資料被保護在內部,程式的其他包只有通過被授權的操作(方法)才能對欄位進行操作。
- 優點:隱藏實現細節;可以對資料進行驗證。
- 實現如下面程式碼所示,需要注意的是,在golang內,除了slice、map、channel和顯示的指標型別屬於引用型別外,其它型別都屬於值型別。
- 引用型別作為函式入參傳遞時,函式對引數的修改會影響到原始呼叫物件的值;
- 值型別作為函式入參傳遞時,函式體內會生成呼叫物件的拷貝,所以修改不會影響原始呼叫物件。所以在下面GetName中,接收器使用 this *Person 指標物件定義。當傳遞的是小物件,且不需要更改呼叫物件時,使用值型別做為接收器;大物件或者需要更改呼叫物件時使用指標型別作為接收器。
type Person struct { name string age int } func NewPerson() Person { return Person{} } func (this *Person) SetName(name string) { this.name = name } func (this *Person) GetName() string { return this.name } func (this *Person) SetAge(age int) { this.age = age } func (this *Person) GetAge() string { return this.age } func main() { p := NewPerson() p.SetName("xiaofei") fmt.Println(p.GetName()) }
2、繼承
- 基本介紹:當多個結構體存在相同的屬性(欄位)和方法時,可以從這些結構體中抽象出一個基結構體A,在A中定義這些相同的屬性和方法。其他的結構體不需要重新定義這些屬性和方法,只需巢狀一個匿名結構體A即可。
- 優點:可以解決程式碼複用,讓程式設計更加靠近 人類思維。
- 實現:在golang中,如果一個struct嵌套了另一個匿名結構體,那麼這個結構體可以直接訪問匿名結構體的欄位和方法,從而實現繼承特性。
- 同時,一個struct還可以巢狀多個匿名結構體,那麼該struct可以直接訪問巢狀的匿名結構體的欄位和方法,從而實現多重繼承。
type Student struct {
Person
StuId int
}
func (this *Student) SetId(id int) {
this.StuId = id
}
func (this *Student) GetId() int {
return this.StuId
}
func main() {
stu := oop.Student{}
stu.SetName("xiaofei") // 可以直接訪問Person的Set、Get方法
stu.SetAge(22)
stu.SetId(123)
fmt.Printf("I am a student,My name is %s, my age is %d, my id is %d", stu.GetName(), stu.GetAge(), stu.GetId)
}
3、抽象
將共同的屬性和方法抽象出來形成一個不可以被例項化的型別,由於抽象和多型是相輔相成的,或者說抽象的目的就是為了實現多型。
4、多型
- 基本介紹:基類指標可以指向任何派生類的物件,並在執行時繫結最終呼叫的方法的過程被稱為多型。多型是執行時特性,而繼承則是編譯時特性,也就是說繼承關係在編譯時就已經確定了,而多型則可以實現執行時的動態繫結。
- 實現:
// 小狗和小鳥都是動物,都會移動和叫,它們共同的方法就可以提煉出來定義為一個抽象的介面。
type Animal interface {
Move()
Shout()
}
type Dog struct {
}
func (dog Dog) Move() {
fmt.Println("I am dog, I moved by 4 legs.")
}
func (dog Dog) Shout() {
fmt.Println("WANG WANG WANG")
}
type Bird struct {
}
func (bird Bird) Move() {
fmt.Println("I am bird, I fly with 2 wings")
}
func (bird Bird) Shout() {
fmt.Println("ji ji ji ")
}
type ShowAnimal struct {
}
func (s ShowAnimal) Show(animal Animal) {
animal.Move()
animal.Shout()
}
func main() {
show := ShowAnimal{}
dog := Dog{}
bird := Bird{}
show.Show(dog)
show.Show(bird)
}
參考資料: