Go語言封裝、繼承、介面、多型和斷言的案例

安全劍客發表於2019-08-19
Go語言開發者認為:物件導向就是特定型別(結構體)有著自己的方法,利用這個方法完成物件導向程式設計,並沒有提封裝、繼承、多型。所以Go語言進行物件導向程式設計時,重點在於靈活使用方法。Go語言有著自己對物件導向的理解,它也有著自己的封裝、繼承、多型。
封裝
    //Learn_Go/main.go
    package main
     
    import (
    	"fmt"
    )
     
    type People struct {
    	name string
    	age int
    }
     
    func (p *People) SetName(name string)  {
    	p.name = name
    }
     
    func (p *People) SetAge(age int)  {
    	p.age = age
    }
     
    func (p *People) GetName() string{
    	return p.name
    }
     
    func (p *People) GetAge() int{
    	return p.age
    }
     
    func main()  {
    	peo := new(People)
    	peo.SetName("derek")
    	peo.SetAge(22)
    	fmt.Println(peo.GetName(),peo.GetAge())     //derek 22
    }
繼承
    //Learn_Go/main.go
    package main
     
    import "fmt"
     
    type People struct {
    	name string
    	age int
    }
     
    type Teacher struct {
    	People
    	classroom string
    }
     
    func main()  {
    	tea := Teacher{People{"derek",22},"911"}
    	fmt.Println(tea.classroom,tea.name,tea.age)    //911 derek 22
    }
介面

介面是一組行為規範的定義;介面中只能有方法宣告,方法只能有名次、引數、返回值,不能有方法體;每個介面中可以有多個方法,結構體把介面總所有方法都重寫後,結構體就屬於介面型別;Go語言中介面和結構體之間的關係是傳統物件導向中is-like-a的關係。

    //Learn_Go/main.go
    package main
     
    import "fmt"
     
    type Live interface {
    	run(i int)
    	eat(thing string)
    }
     
    type People struct {
    	name string
    }
     
    func (p *People) run(i int)  {
    	fmt.Println(p.name,"跑了",i,"米")
    }
     
    func (p *People) eat(thing string)  {
    	fmt.Println(p.name,"正在吃",thing)
    }
     
    func main()  {
    	peo := People{"derek"}
    	peo.run(100)
    	peo.eat("麵包")
    }
多型

多型:同一件事情由於條件不同產生的結果不同;由於go語言中結構體不能相互轉換,所以沒有結構體的多型,只有基於介面的多型。

    //Learn_Go/main.go
    package main
     
    import "fmt"
     
    type Live interface {
    	run()
    }
     
    type People struct {
    	name string
    }
     
    type Animal struct {
    	name string
    }
     
    func (p *People) run()  {
    	fmt.Printf("%v在跑步",p.name)
    }
     
    func (a *Animal) run()  {
    	fmt.Printf("%v在跑步",a.name)
    }
     
    func allrun(live Live)  {
    	live.run()
    }
     
    func main()  {
    	//介面不能例項化,只能對介面的結構體例項化
    	peo := &People{"derek"}
    	allrun(peo)      //derek在跑步
    	//多型,條件不同結果不同
    	a := &Animal{"小狗"}
    	allrun(a)       //小狗在跑步
    }
斷言

只要實現了介面的全部方法認為這個型別屬於介面型別,如果編寫一個介面,這個介面沒有任何方法,這是認為所有型別都是了這個介面,所以Go語言中interface{}代表任意型別;如果interface{]作為方法引數就可以接受任意型別,但是在程式中有時有需要知道這個引數到底是什麼型別,這個時候就需要使用斷言。

(1)斷言可以有一個返回值,如果判斷結果是指定型別返回變數值,否則報錯

    //Learn_Go/main.go
    package main
     
    import "fmt"
     
    func main()  {
    	var i interface{} = 44     //i是int型別
    	result1 := i.(int)
    	fmt.Println(result1)     //44
     
    	result2 := i.(string)
    	fmt.Println(result2)    //panic: interface conversion: interface {} is int, not string
    }

(2)可以檢視值的型別 

    //Learn_Go/main.go
    package main
     
    import "fmt"
     
    func main()  {
    	var i interface{} = 44     //i是int型別
    	result,ok := i.(int)
    	fmt.Println(result,ok)     //44 true
    	fmt.Printf("%T",result)    //int
    }

(3)透過斷言判斷值的型別

    //Learn_Go/main.go
    package main
     
    import "fmt"
     
    func demo(i interface{})  {
    	_,ok := i.(int)
    	if ok{
    		fmt.Println("參是int型別")
    		return
    	}
    	_,ok = i.(string)
    	if ok{
    		fmt.Println("參是string型別")
    		return
    	}
    	fmt.Println("引數型別不確定,不是int和string型別")
    }
     
    func main()  {
    	demo(8)            //參是int型別
    	demo("derek")      //參是string型別
    	demo(3.146)        //引數型別不確定,不是int和string型別
    }


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559985/viewspace-2654198/,如需轉載,請註明出處,否則將追究法律責任。

相關文章