接口interface
尚硅谷Golang課

接口interface

例如定義 只要滿足"會跑"且"會叫"的就是"動物",

那不管你是啥玩意只要實現會跑跟會叫,我就當你是動物,就能用動物的接口去調用

//接口內不能有變量,方法也不能實現
type Usb interface {
	//聲明兩個沒實現的方法
	Start()
	Stop()
}

type Usb2 interface {
	//接口是不需要顯示聲明,只要能實現就都能調用
	Start()
	Stop()
	//假如我多聲明一個沒實現的方法在接口內就不能調用
	Test() //有方法沒實現,導致Usb2這個接口不能用
}
type Phone struct {
}

//讓Phone實現USB接口的方法
func (p Phone) Start() {
	fmt.Println("手機啟動")
}
func (p Phone) Stop() {
	fmt.Println("手機停止")
}

type Camera struct {
}

func (c Camera) Start() {
	fmt.Println("相機啟動~~")
}
func (c Camera) Stop() {
	fmt.Println("相機停止")
}

//電腦
type Computer struct {
}

func (c Computer) Working(usb Usb) { //接受一個Usb的接口類型
	//通過usb變量來調用Start等方法
	fmt.Println("電腦連接usb中...")
	usb.Start()
	usb.Stop()

}
func main() {
	computer := Computer{}
	phone := Phone{}
	camera := Camera{}

	//關鍵
	computer.Working(phone)
	computer.Working(camera)
}

接口繼承

繼承主要在於復用性跟可維護性 接口價值在於擴展性(設計好規範(方法),讓其他類型去實現

繼承是 is a的關係 例如 學生是個人 接口是 like a的關係 例如 學生會說英語

func (m *Monkey) climb() {
	fmt.Println(m.Name, "生來會爬樹")
}

//聲明接口
type BirdAble interface {
	Flying()
}

func (lm *LittleMonkey) Flying() {
	fmt.Println(lm.Name, "學會飛了")
}

func main() {
	var monkey1 LittleMonkey
	monkey1.Name = "悟空"
	monkey1.climb()
	monkey1.Flying()

}

接口實踐排序

type Hero struct {
	Name string
	Age  int
}

//聲明一個Hero結構體的切片類型
type HeroSlice []Hero

//實現接口
func (hs HeroSlice) Len() int {
	return len(hs)
}

func (hs HeroSlice) Less(i, j int) bool {
	//return hs[i].Age < hs[j].Age //Less就是決定使用哪個字段來排序
	return hs[i].Name < hs[j].Name //Less就是決定使用哪個字段來排序
}

func (hs HeroSlice) Swap(i, j int) {
	hs[i], hs[j] = hs[j], hs[i]
}

func main() {
	//定義一個數組跟切片
	var intSlice = []int{5, 3, 1, 2, 4}
	//來排序
	sort.Ints(intSlice)
	fmt.Println(intSlice)

	//系統提供的方法

	//創建切片內容
	var heroes HeroSlice
	for i := 0; i < 10; i++ {
		hero := Hero{
			Name: fmt.Sprintf("英雄%d", rand.Intn(100)),
			Age:  rand.Intn(100),
		}
		//放進切片 隨機創建了十個hero放進heroes這個切片
		heroes = append(heroes, hero)
	}

	//排序前
	for _, v := range heroes {
		fmt.Println(v)
	}

	//調用sort.Sort
	sort.Sort(heroes)
	//因為我的結構體能實現接口,就可以享受這些方便
	fmt.Println("---排序後---")
	for _, v := range heroes {
		fmt.Println(v)
	}
}

類型斷言

func TypeJudge(items ...interface{}) {
	for index, x := range items {
		switch x.(type) {
		case bool:
			fmt.Printf("第%v個參數是bool類型,值是%v\n", index+1, x)
		case int, int32, int64:
			fmt.Printf("第%v個參數是int類型,值是%v\n", index+1, x)
		case string:
			fmt.Printf("第%v個參數是string類型,值是%v\n", index+1, x)
		default:
			fmt.Printf("第%v個參數是不明類型,值是%v\n", index+1, x)
		}
	}
}

func main() {
	var n1 float64 = 2.3
	var n2 int = 30
	var name string = "tom"
	n4 := 300

	TypeJudge(n1, n2, name, n4)
}

上次修改於 2021-08-01

此篇文章的評論功能已經停用。