接口
接口的定义
type Shape interfance {Area() float64Perimeter() float64}
- interface,structs,methods 可以实现面向对象的特性
- interface是一系列方法的声明
接口有两个类型
- static 和 dynamic 类型
接口的零值是nil
package mainimport "fmt"type Shape interface{Area() intPerimeter() int}type Rect struct {width intlength int}func (s Rect) Area() int {return s.width * s.length}func (s Rect) Perimeter() int {return 2 * (s.width + s.length)}func main() {var r Shape = Rect{ 5.0, 4.0 }fmt.Println(r.Area())fmt.Println(r.Perimeter())}
空接口
若在接口中没有声明方法,则说明该接口是空接口
_
内置fmt包中fmt接收的就是可变参数个数的函数,参数的类型是空接口
func Println(a ...interface{}) (n int, err error)
多接口
结构体可以继承多接口
package mainimport "fmt"type Shape interface {Area() float64}type Object interface {Volume() float64}type Cube struct {side float64}func (c Cube) Area() float64 {return c.side * c.side}func (c Cube) Volume() float64 {return c.side * 2}func main() {c := Cube{3}fmt.Println(c.Area())fmt.Println(c.Volume())}
类型断言(Type assertion)
上面改的例子, 如果将
c := Cube{3}
改成
c := Cube{3}
var s Shape = c
后,调用 s.Volume() 方法就会出现异常
可以通过 类型声明 的特性改造上面的例子:
func main() {var s shape = Cube(3)c := s.(Cube)fmt.Println(c.Area())fmt.Println(c.Volume())}
判断变量是否是混合类型
value, ok := i.(Type)
- 若ok=false, value是nil
Type Switch
- i.(type) 用来获取变量的类型
- i.(type) 用来转换变量的类型, 如i.(string)
package mainimport ("fmt""strings")func explain(i interface{}) {switch i.(type) {case string:fmt.Println("i store string ", strings.ToUpper(i.(string)))case int:fmt.Println("i store int ", i.(int))default:fmt.Println("i store something other ", i)}}func main() {explain("Hello world")explain(53)}
嵌套的接口
- 内嵌的接口就想内嵌的结构体一样,如果子接口的方法会自动上升到父接口
package maintype Shape interface {Area() float64}type Object interface {Volume() float64}type Material interface {ShapeOjbect}func main() {c := Cube{3}var m Material = cvar s Shape = cvar o Object = c}
接口方法的接收者是指针还是普通类型值
- 如果实现接口的struct接收者是指针
package mainimport "fmt"type Shape interface {Area() intPerimeter() int}type Rect struct{length intwidth int}func (r *Rect) Area() int {return r.length * r.width}func (r Rect) Perimeter() int {return 2 * (r.length + r.width)}func main() {r := Rect {5, 4}var s Shape = &r // 由于方法接收者是指针fmt.Println("Rect area is ", s.Area())fmt.Println("Rect area is ", s.Perimeter())}
