1. 程式人生 > 其它 >golang實現面向物件的封裝、繼承、多型

golang實現面向物件的封裝、繼承、多型

1. 基本介紹

面向物件程式設計(Object Oriented Programming,OOP)是一種計算機程式設計框架,儘可能的模擬人類的思維方式,使得軟體的開發方法與過程儘可能接近人類認識世界、解決現實問題的方法和過程。

封裝、繼承、多型和抽象是面向物件的4個基本特徵。

2. golang的面向物件型別

  1. golang實現面向物件的兩個關鍵型別是struct 和interface,struct類似於C++的普通類型別,interface則對應抽象類型別。
  2. 同時與其他語言採用public、private、protected指示成員和方法的可見性不同,golang採用首字母大小寫來標識成員/方法的可見性,小寫字母開頭表示私有成員,大寫字母開頭表示對外可見。

1、封裝

  1. 基本介紹:封裝就是把抽象出的欄位和欄位的操作封裝在一起,資料被保護在內部,程式的其他包只有通過被授權的操作(方法)才能對欄位進行操作
  2. 優點:隱藏實現細節;可以對資料進行驗證。
  3. 實現如下面程式碼所示,需要注意的是,在golang內,除了slice、map、channel和顯示的指標型別屬於引用型別外,其它型別都屬於值型別。
    1. 引用型別作為函式入參傳遞時,函式對引數的修改會影響到原始呼叫物件的值;
    2. 值型別作為函式入參傳遞時,函式體內會生成呼叫物件的拷貝,所以修改不會影響原始呼叫物件。所以在下面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、繼承

  1. 基本介紹:當多個結構體存在相同的屬性(欄位)和方法時,可以從這些結構體中抽象出一個基結構體A,在A中定義這些相同的屬性和方法。其他的結構體不需要重新定義這些屬性和方法,只需巢狀一個匿名結構體A即可。
  2. 優點:可以解決程式碼複用,讓程式設計更加靠近 人類思維。
  3. 實現:在golang中,如果一個struct嵌套了另一個匿名結構體,那麼這個結構體可以直接訪問匿名結構體的欄位和方法,從而實現繼承特性。
  4. 同時,一個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、多型

  1. 基本介紹:基類指標可以指向任何派生類的物件,並在執行時繫結最終呼叫的方法的過程被稱為多型。多型是執行時特性,而繼承則是編譯時特性,也就是說繼承關係在編譯時就已經確定了,而多型則可以實現執行時的動態繫結。
  2. 實現:
// 小狗和小鳥都是動物,都會移動和叫,它們共同的方法就可以提煉出來定義為一個抽象的介面。
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)
}

參考資料:

  1. https://blog.csdn.net/weixin_44736475/article/details/114222071
  2. https://blog.csdn.net/weixin_44736475/article/details/114177630
  3. https://blog.csdn.net/weixin_44736475/article/details/114181543
  4. https://blog.csdn.net/m0_37554486/article/details/77404739