go 语言学习笔记(12)——接口
接口关心的是行为, 不关心对象是什么类型的
不能实例化
但可以用用户定义类型实现
接口定义
type palyer interface {
SayHi()
}
接口命名习惯以er结尾
只用方法声明, 没有实现, 没有数据字段
接口可以匿名函数嵌入其他接口, 或者嵌入到结构中
实例化
只要实现了此接口方法的类型, 那么类型的变量就可以给接口类型变量赋值
eg
package main
import "fmt"
type Student struct {
name string
id int
}
type Teacher struct {
add string
group int
}
type Mystring string
type palyer interface {
SayHi()
}
func (t *Student) SayHi() {
fmt.Println("这是名字为", t.name, "学生打招呼")
}
func (t *Teacher) SayHi() {
fmt.Println("这是地址为", t.add, "老师打招呼")
}
func (t *Mystring) SayHi() {
fmt.Printf("这是%s打招呼 ", *t)
}
func main() {
var i palyer
s := &Student{"hxw", 19}
i = s
i.SayHi()//这是名字为 hxw 学生打招呼
t := &Teacher{"bj", 20}
i = t
i.SayHi()//这是地址为 bj 老师打招呼
var str Mystring = "123"
i = &str
i.SayHi()//这是123打招呼
}
调用同一个函数, 有不同的表现形式
接口接片
package main
import "fmt"
type Student struct {
name string
id int
}
type Teacher struct {
add string
group int
}
type Mystring string
type palyer interface {
SayHi()
}
func (t *Student) SayHi() {
fmt.Println("这是名字为", t.name, "学生打招呼")
}
func (t *Teacher) SayHi() {
fmt.Println("这是地址为", t.add, "老师打招呼")
}
func (t *Mystring) SayHi() {
fmt.Printf("这是%s打招呼 ", *t)
}
func main() {
s := &Student{"hxw", 19}
t := &Teacher{"bj", 20}
var str Mystring = "123"
x := make([]palyer, 3)
x[0] = s
x[1] = t
x[2] = &str
for _, i := range x {//第一个返回下标, 第二个返回接口
i.SayHi()
}
}
//这是名字为 hxw 学生打招呼
//这是地址为 bj 老师打招呼
//这是123打招呼
接口继承
通过匿名字段
type palyer interface { //子集
SayHi()
}
type Personer interface { //超集
palyer
sing(str string)
}
package main
import "fmt"
type Student struct {
name string
id int
}
type Palyer interface { //子集
SayHi()
}
type Personer interface { //超集
Palyer
sing(str string)
}
func (t *Student) SayHi() {
fmt.Println("这是名字为", t.name, "学生打招呼")
}
func (t *Student) sing(str string) {
fmt.Println(t.name, "唱", str)
}
func main() {
s := &Student{"hxw", 19}
var i Personer
i = s
i.SayHi()//继承过来的方法
//这是名字为 hxw 学生打招呼
i.sing("sghl")
//hxw 唱 sghl
}
超集可以转化为子集 子集不能转化为子集
Palyer 不可以转化为Personer 反过来可以
空接口
空接口不包含任何方法, 所有类型都实现了空接口, 可以随意储存任意类型的值
万能类型的值
var i interface{} = 1
fmt.Println(i)//1
i = "abc"
fmt.Println(i)//abc