Go语言入门(十一) 接口编程
接口
接口的定义
接口定义了一个对象化的行为规范
- 只定义规范,不实现
- 具体的对象需要实现规范的细节
- 实践
- type 定义接口 interface
- 接口里面是一组方法签名的集合
type Animal interface { Talk() Eat() Run() }
- 实现
- 一个对象只要包含接口中的方法,那么就实现了这个接口
- 接口类型的变量可以保存实现该接口的任何类型的实例
type Animal interface { Talk() Eat() Run() } type Dog struct { name string } //一个对象只要包含接口中的方法,那么就实现了这个接口 func (d *Dog) Eat() { fmt.Printf("%s is eating\n",d.name) } func (d *Dog) Talk() { fmt.Printf("%s is talking\n",d.name) } func (d *Dog) Run() { fmt.Printf("%s is running\n",d.name) } func main() { var dog = &Dog{ name: "旺财", } var a Animal //接口类型的变量可以保存实现该接口的任何类型的实例 a = dog a.Eat() a.Run() a.Talk() fmt.Printf("a:%v,dog:%v\n",a,dog) }
接口实例
- 计算公司所有职员的薪水
- 每个职员的计算方式不同
结构体实现
type Developer struct { Name string Base float64 } func (d *Developer)Calc() float64{ return d.Base } type PM struct { Name string Base float64 Option float64 } func (p *PM)Calc() float64{ return p.Base + p.Option } type YY struct { Name string Base float64 Ratio float64 Option float64 } func (y *YY)Calc() float64 { return y.Base + y.Option * y.Ratio } type EmployeeMgr struct { devlist []*Developer pmlist []*PM yylist []*YY } func (e *EmployeeMgr)Calc() float64 { var sum float64 for _,v := range e.devlist { sum += v.Calc() } for _,v1 := range e.pmlist { sum += v1.Calc() } for _,v2 := range e.yylist { sum += v2.Calc() } return sum } func (e *EmployeeMgr)AddDev(d *Developer) { e.devlist = append(e.devlist, d) } func (e *EmployeeMgr)AddPM(p *PM) { e.pmlist = append(e.pmlist, p) } func (e *EmployeeMgr)AddYY(y *YY) { e.yylist = append(e.yylist, y) } func main() { var e = &EmployeeMgr{} dev := &Developer{ Name: "develop", Base: 5000, } e.AddDev(dev) pm := &PM{ Name: "pm", Base: 10000, Option: 2000, } e.AddPM(pm) yy := &YY{ Name: "yy", Base: 23000, Option: 9000, Ratio: 0.67, } e.AddYY(yy) sum := e.Calc() fmt.Printf("sum:%.2f\n",sum) }
接口实现
type Employee interface { Calc() float64 //接口返回 } type Developer struct { Name string Base float64 } func (d *Developer)Calc() float64{ return d.Base } type PM struct { Name string Base float64 Option float64 } func (p *PM)Calc() float64{ return p.Base + p.Option } type YY struct { Name string Base float64 Ratio float64 Option float64 } func (y *YY)Calc() float64 { return y.Base + y.Option * y.Ratio } type EmployeeMgr struct { employeelist []Employee } func (e *EmployeeMgr) Calc() float64 { var sum float64 for _,v := range e.employeelist { sum += v.Calc() } return sum } func (e *EmployeeMgr) AddEmployee(d Employee) { e.employeelist = append(e.employeelist,d) } func main() { var e = &EmployeeMgr{} dev := &Developer{ Name: "develop", Base: 5000, } e.AddEmployee(dev) pm := &PM{ Name: "pm", Base: 10000, Option: 2000, } e.AddEmployee(pm) yy := &YY{ Name: "yy", Base: 23000, Option: 9000, Ratio: 0.67, } e.AddEmployee(yy) sum := e.Calc() fmt.Printf("sum:%.2f\n",sum) }
空接口
- 空接口没有定义任何方法
- 所以了任何类型都实现了空接口
func main() { var a interface{} var b int a = b fmt.Printf("a=%v,a:%T\n",a,a) var c float64 a = c fmt.Printf("a=%v,a:%T\n",a,a) }
类型断言
- 需要引入v,ok := i(T)机制
func Describe(a Animal) { /*代码有坑 dog := a.(*Dog) dog.Eat() */ dog,ok := a.(*Dog) if !ok { fmt.Printf("convert to dog error\n") return } fmt.Printf("describe dog succ\n") dog.Run() fmt.Printf("describe dog succ------\n") }
- 类型断言
func DescribeSwitch(a Animal) { fmt.Printf("DescribeSwitch(a) Begin\n") switch a.(type) { case *Dog: dog := a.(*Dog) dog.Run() case *Pig: pig := a.(*Pig) pig.Eat() } fmt.Printf("DescribeSwitch(a) End\n") }
- 类型断言改进版
func DescribeSwitch(a Animal) { fmt.Printf("DescribeSwitch(a) Begin\n") switch v:=a.(type) { case *Dog: dog := v dog.Run() case *Pig: pig := v pig.Eat() } fmt.Printf("DescribeSwitch(a) End\n") }
- 指针接收
- 同一个类型可以实现多个接口
type Animal interface { Talk() Eat() Run() } type BuRuAnimal interface { ChiNai() } type Dog struct { name string } //一个对象只要包含接口中的方法,那么就实现了这个接口 func (d Dog) Eat() { fmt.Printf("%s is eating\n",d.name) } func (d Dog) Talk() { fmt.Printf("%s is talking\n",d.name) } func (d Dog) Run() { fmt.Printf("%s is running\n",d.name) } func (d Dog) ChiNai() { fmt.Printf("%s is chinai\n",d.name) } func main() { var dog = &Dog{ name: "旺财", } var a Animal //接口类型的变量可以保存实现该接口的任何类型的实例 a = dog //Describe(a) //DescribeSwitch(a) a.Eat() var dogVar = Dog{name:"来福"} a = dogVar a.Run() //实现多个接口 var b BuRuAnimal b = dog b.ChiNai() }
- 接口嵌套
type Animal interface { Talk() Eat() Run() } type BuRuAnimal interface { ChiNai() } type AdvanceAnimal interface { Animal BuRuAnimal } type Dog struct { name string } //一个对象只要包含接口中的方法,那么就实现了这个接口 func (d Dog) Eat() { fmt.Printf("%s is eating\n",d.name) } func (d Dog) Talk() { fmt.Printf("%s is talking\n",d.name) } func (d Dog) Run() { fmt.Printf("%s is running\n",d.name) } func (d Dog) ChiNai() { fmt.Printf("%s is chinai\n",d.name) } func main() { var dog = &Dog{ name: "旺财", } var a AdvanceAnimal a = dog a.ChiNai() }
接口实例详解
- io包中的writer接口
type Test struct { data string } func (t *Test)Write(p []byte) (n int,err error) { t.data = string(p) return len(p),nil } func FprintfDemo() { file,_ := os.Create("./a.txt") fmt.Fprintf(os.Stdout,"hello world\n") fmt.Fprintf(file,"hello World\n") //终端文件写入 var t *Test = &Test{} //将字符串写入内存,然后再读取 fmt.Fprintf(t,"this is a test interface %s","dasdada") fmt.Printf("t.data=%s\n",t.data) }
- fmt包中的Stringer接口
返回字符串
type Student struct { Name string Age int } func (s *Student)String()string { data,_ := json.Marshal(s) return string(data) } func main() { var s = &Student{ Name: "ABC", Age: 22, } fmt.Printf("s = %v\n",s) }
- error接口
type MyError struct { When time.Time What string } func (e *MyError) Error()string{ str:= fmt.Sprintf("time=%v,message=%s\n",e.When,e.What) fmt.Printf("1:%T\n",str) return str } func run()error { fmt.Printf("0\n") str:=MyError{time.Now(),"it did not work well"} fmt.Printf("2:%T\n",str) fmt.Printf("%v,%s\n",time.Now(),"error to run!!") return &str } func main() { if err := run();err!=nil { fmt.Printf("3:%T\n",err) fmt.Println(err) } }
相关推荐
哈嘿Blog 2020-09-08
free0day 2020-07-06
huimeiad 2020-11-23
往后余生 2020-09-17
hushijiao 2020-11-10
lxhuang 2020-11-03
womystery 2020-10-15
Martian 2020-10-13
luguanyou 2020-10-05
夜影风个人空间 2020-09-22
LittleCoder 2020-09-11
0linker 2020-09-01
libaoshan 2020-09-11
saluzirobot 2020-09-01
txq0 2020-08-24
充满诗意的联盟 2020-08-23
jaybeat 2020-08-20
浪味仙 2020-08-17
ChinaJoeEE 2020-08-16