阅读目录
- 值类型实现接口
- 指针接收
- 1 值类型接口
- 2 指针类型接口
- 实现多接口
- 1 同一个类型可以实现多个接口
- 2 接口嵌套,和结构体嵌套类似
值类型实现接口
package main
import "fmt"
type Animal interface {
Talk()
Eat()
Name() string
}
type Dog struct {
}
func (d Dog) Talk() {
fmt.Println("汪汪汪")
}
func (d Dog) Eat() {
fmt.Println("我在吃骨头")
}
func (d Dog) Name() string {
fmt.Println("我的名字叫旺财")
return "旺财"
}
func main() {
var a Animal
var d Dog
a = d
a.Eat()
fmt.Printf("%T %v\n", a, a)
}
PS E:\TEXT\test_go\two> go run .\main.go
我在吃骨头
main.Dog {}
PS E:\TEXT\test_go\two>
指针接收
以下是,1 值类型接口 和 2 指针类型接口的区别示例。
1 值类型接口
接口变量里及可以存值类型,也可以存指针类型。
指针类型是没有实现 Eat 值类型这个接口的,那么接口里面进行一个转换。
首先取出地址 &Dog
,然后对地址取值 *(&Dog)
就变成值类型了,值类型就实现了 Eat 这个方法,所以就调用了。
package main
import "fmt"
type Animal interface {
Talk()
Eat()
Name() string
}
type Dog struct {
}
func (d Dog) Talk() {
fmt.Println("汪汪汪")
}
func (d Dog) Eat() {
fmt.Println("我在吃骨头")
}
func (d Dog) Name() string {
fmt.Println("我的名字叫旺财")
return "旺财"
}
func main() {
var a Animal
var d Dog
a = d
a.Eat()
fmt.Printf("%T %v\n", a, a)
/*
指针类型是没有实现 Eat 值类型这个接口的,
那么接口里面进行一个转换。
首先取出地址 &Dog,然后对地址取值 *(&Dog) 就变成值类型了,
值类型就实现了 Eat 这个方法,所以就调用了。
*/
var d1 *Dog = &Dog{}
a = d1
a.Eat()
fmt.Printf("*Dog %T %v", a, a)
}
2 指针类型接口
package main
import "fmt"
type Animal interface {
Talk()
Eat()
Name() string
}
type Dog struct {
}
func (d *Dog) Talk() {
fmt.Println("汪汪汪")
}
func (d *Dog) Eat() {
fmt.Println("我在吃骨头")
}
func (d *Dog) Name() string {
fmt.Println("我的名字叫旺财")
return "旺财"
}
func main() {
var a Animal
var d Dog
/*
a 存的是是一个值类型的 Dog,那么调用 a.Eat(),首先要去去 &Dog->Eat()
如果一个变量存储在接口类型的变量中之后,那么不能获取这个变量的地址。
*/
// a = d 这样是存不进去的。
a = &d
a.Eat()
fmt.Printf("%T %v\n", a, a)
var d1 *Dog = &Dog{}
a = d1
a.Eat()
fmt.Printf("*Dog %T %v", a, a)
}
实现多接口
1 同一个类型可以实现多个接口
package main
import "fmt"
type Animal interface {
Talk()
Eat()
Name() string
}
type PuruDongWu interface {
TaiSheng()
}
type Dog struct {
}
func (d Dog) Talk() {
fmt.Println("汪汪汪")
}
func (d Dog) Eat() {
fmt.Println("我在吃骨头")
}
func (d Dog) Name() string {
fmt.Println("我的名字叫旺财")
return "旺财"
}
func (d Dog) TaiSheng() {
fmt.Println("狗是胎生的")
}
func main() {
var d Dog
var a Animal
fmt.Println("%v %T %p", a, a, a)
a = d
a.Eat()
// 判断 a 有没有存具体的类型
if a == nil {
// a.Eat() 不能直接使用,需要初始化。
fmt.Println("a is nil")
}
var b PuruDongWu
b = d
b.TaiSheng()
}
2 接口嵌套,和结构体嵌套类似
package main
import "fmt"
type Animal interface {
Talk()
Eat()
Name() string
}
type Describle interface {
Describle() string
}
type AdvanceAnimal interface {
Animal
Describle
}
// AdvanceAnimal 包含以上四个方法
// 实现 AdvanceAnimal 接口
type Dog struct{}
func (d Dog) Talk() {
fmt.Println("汪汪汪")
}
func (d Dog) Eat() {
fmt.Println("我在吃骨头")
}
func (d Dog) Name() string {
fmt.Println("我的名字叫旺财")
return "旺财"
}
func (d Dog) Describle() string {
fmt.Println("dog is a dong")
return "dog is a dog"
}
func main() {
var d Dog
var a AdvanceAnimal
a = d
a.Describle()
a.Eat()
a.Talk()
a.Name()
}
PS E:\TEXT\test_go\two> go run .\main.go
dog is a dong
我在吃骨头
汪汪汪
我的名字叫旺财
PS E:\TEXT\test_go\two>