day08 Go中的物件導向

染指未来發表於2024-07-02

go 物件導向繼承

  • Go語言的繼承:結構體的巢狀
package main

import "fmt"

// 父類結構體
type Person struct {
	name string
	age  int
}

// 子類結構體。 Student 使用了 匿名繼承。表示 Student中擁有了 Person的所有欄位
type Student struct {
	Person // 匿名欄位,實現了繼承
	school string
}

func main() {
	// CTO  業務功能拆分,軟體架構選型。
	/*
		go 中如何實現物件導向
			- 封裝
			- 繼承
			- 多型 宏觀事物
	*/

	// 繼承:父類通用,子類具體。 go語言中就是:結構體的巢狀

	// 定義 父類
	p1 := Person{name: "zhangsna", age: 19}
	fmt.Println(p1)

	// 定義 子類
	s1 := Student{Person: Person{
		"lisi",
		30,
	}, school: "清華"}
	fmt.Println(s1)

	// 定義子類
	var s2 Student
	s2.Person.name = "王五"
	s2.Person.age = 32
	s2.school = "北大"
	fmt.Println(s2)

	// 定義子類
	// 提升結構體欄位:只有使用 `匿名欄位` 才可以使用。即:Person在Student是一個匿名欄位,Person中的name,age屬效能直接被點出來
	var s3 Student
	s3.name = "趙六" // 提升欄位,直接使用Person結構體中的name
	s3.age = 23    // 提升欄位,直接使用Person結構體中的age
	s3.school = "科技大學"
	fmt.Println(s3)

}

go 物件導向中的方法

  • 結構體能夠呼叫該方法 , 也是物件導向中的方法
package main

import "fmt"

type Dog struct {
	name string
	age  int
}

// 定義 一個帶結構體引數的函式方法。即:結構體能夠呼叫該方法 , 也是物件導向中的方法
func (dog Dog) eat() {
	fmt.Println("Dog has func eat ")
}

// 物件屬性
type Cat struct {
	name string
	age  int
}

// 物件方法
func (cat Cat) eat() {
	fmt.Println("Cat has func eat ")
}
func (cat Cat) sleep() {
	fmt.Println("Cat has func sleep ")
}
func main() {
	/* go 語言中 物件導向的中的方法. 模擬成一個類 */

	dog := Dog{"金毛狗🐶", 30}
	dog.eat()
	cat := Cat{"布偶貓🐱", 21}
	cat.eat()
	cat.sleep()

}

go 物件導向中的方法。【高階使用】方法繼承/重寫

package main

import "fmt"

// 定義 父類
type Animal struct {
	name string
	age  int
}

// 定義父類的通用方法
func (a Animal) sleep() {
	fmt.Println(a.name, "正在睡覺。。。")
}
func (a Animal) eat() {
	fmt.Println(a.name, "正在吃飯。。。")

}

// 定義 Dog1 子類,並繼承 Animal
type Dog1 struct {
	Animal
}
type Dog2 struct {
	Animal
	color string
}

// 定義子類自己的方法
func (dog Dog1) bite() {
	fmt.Println(dog.name, "正在咬人。。。")

}

// 定義 Cat1 子類,並繼承 Animal
type Cat1 struct {
	Animal
	color string // 定義子類自己的屬性
}

// Cat1 重寫 父類的方法
func (cat Cat1) eat() {
	fmt.Println("Cat1 重寫 父類的 eat 方法:", cat.name, "正在吃貓糧")
}

func main() {
	golden_retriever := Dog1{Animal{name: "小金毛", age: 3}}
	ragdoll := Cat1{Animal: Animal{name: "布偶", age: 3}, color: "奶白色"}
	// 1. 子類使用父類的方法
	golden_retriever.eat()
	golden_retriever.sleep()

	// 2. 子類使用自己的方法
	fmt.Println("子類使用自己的方法:")
	golden_retriever.bite()

	// 3. 子類使用父類的屬性
	fmt.Println("子類使用父類的屬性:", ragdoll.name, ragdoll.age)
	// 4. 子類使用子類的屬性
	fmt.Println("子類使用子類的屬性:", ragdoll.color)

}

go 物件導向中的多型

  • go 中的多型,需要 go 的interface 介面來實現
package main

import "fmt"

// AnimalInterface 定義介面
type AnimalInterface interface {
	eat()
	sleep()
}

type DogInterfaceStruct struct {
	name string
}
type CatInterfaceStruct struct {
	name string
}

func (d DogInterfaceStruct) eat() {
	fmt.Println("多型狗狗🐶:", d.name, "正在吃")
}
func (d DogInterfaceStruct) sleep() {
	fmt.Println("多型狗狗🐶:", d.name, "正在睡覺")

}

func (c CatInterfaceStruct) eat() {
	fmt.Println("多型騷貓🐱:", c.name, "正在吃")

}
func (c CatInterfaceStruct) sleep() {
	fmt.Println("多型騷貓🐱:", c.name, "正在睡覺")

}

func realizePolymorphism(animal AnimalInterface) {
	animal.eat()
	animal.eat()
}

func main() {
	/*
		模糊類(結構體)/ 具體類(結構體)
	*/

	// go 中的多型。需要 go 中的interface 介面來實現

	// 多型:一個事物有多種形態

	cat := CatInterfaceStruct{name: "布偶貓"}
	cat.eat()
	cat.sleep()

	dog := DogInterfaceStruct{name: "小雞毛"}
	dog.eat()
	dog.sleep()
	fmt.Println("------")
	// 定義一個型別 可以為 介面型別的變數,實際上所有實現類都可以賦值給這個物件。
	var animal AnimalInterface
	animal = dog
	realizePolymorphism(animal)

	// 總結:介面的實現 都擁有 多型特性,除了自己本身還是它對應的介面型別

}

小結 go 和 python對比物件導向

go 中的物件導向
			struct : `類的定義 / 類中的類屬性 / 物件屬性`
				- 結構體繼承 : python類繼承,繼承不同的類的屬性
				- 定義欄位: python中類的例項化物件的 `屬性`
			struct func: `類中的 類的例項化`
				- 結構體實現方法: python中類例項化物件的 方法
			interface :  `類中的方法/物件方法`
				- 介面是一堆方法的集合: python中類定義一大堆類方法或者物件方法
			interface func `類的初始化,或者多型類的初始化`
				- 介面實現方法,傳入一個介面物件。  python中類的例項化基類的例項化

python中的物件導向
			object 原類
			__init__ 屬性
			- 方法
				- 靜態方法
				- 類方法
				- 物件方法
			- 屬性
				- 類屬性
				- 物件屬性
			- 魔方函式。即帶下劃線的函式
			- 封裝
			- 多型
			- 繼承



}

相關文章