Go语言不是传统的面向对象编程语言,没有类和继承的概念,但是有非常灵活的接口,可以实现面向对象的特征,接口提供一种方式来说明对象的行为
定义接口
type Namer interface {
Method1(param_list) return_type
Method2(param_list) return_type
...
}
接口命名方式
- 方法名 + er后缀(接口只有一个方法的时候)
- 接口以able结尾
- 以大写字母I开头
接口实现规则
- 接口可以被隐式实现,多个类型可以实现同一个接口
- 实现接口的某个类型还可以有其他的方法
- 一个类型可以实现多个接口
// 1. 定义一个接口
type Shaper interface {
Area() float32
}
type Square struct {
side float32
}
// 2. Square类型指针实现接口中的方法
func (sq *Square) Area() float32 {
return sq.side * sq.side
}
type Rectangle struct {
length, width float32
}
// 3. Rectangle类型实现接口中的方法
func (r Rectangle) Area() float32 {
return r.length * r.width
}
func main() {
r := Rectangle{5, 3}
q := &Square{5}
// 4. 通过接口数组接收两个变量
shapes := []Shaper{r, q}
fmt.Println("Looping through shapes for area ...")
for n, _ := range shapes {
fmt.Println("Shape details: ", shapes[n])
// 5. 实现多态
fmt.Println("Area of this shape is: ", shapes[n].Area())
}
}
接口嵌套
- 一个接口可以包含多个接口,相当于将内嵌接口的方法列举在外层接口
// 1. 定义接口ReadWrite和Lock
type ReadWrite interface{
Read(b Buffer) bool
Write(b Buffer) bool
}
type Lock integer{
Lock()
Unlock()
}
// 2. 在接口中添加了两个匿名字段:ReadWrite和Lock,实现接口嵌套
type File interface{
ReadWrite
Lock
Close()
}
接口变量类型断言
接口类型变量可以包含任何类型的值,所以需要在运行时检测变量中存储的值的实际类型
t := varI.(T)
// 或者可以使用下面这种方式
if t, ok := varI.(T); ok {
Process(t)
return
}
varI必须是一个接口类型变量
类型判断(type - switch)
接口变量的类型也可以使用switch来检测
switch t := areaIntf.(type) {
case *Square:
fmt.Printf("Type Square %T with value %v\n", t, t)
case *Circle:
fmt.Printf("Type Circle %T with value %v\n", t, t)
case nil:
fmt.Printf("nil value: nothing to check?\n")
default:
fmt.Printf("Unexpected type %T\n", t)
}
type - switch中不允许有fallthrough
接口方法集调用规则
- 类*T可调用方法集包括接收者为*T和T的所有方法集
- 类型T的可调用方法集包含接收者T的所有方法,但不包含接收者为*T的方法
空接口
type Any interface{}
- 空接口是不包含任何方法的接口
- 任何类型的值都可以赋值给空接口类型变量
入门教程推荐: github.com/Unknwon/the…