接口类型可以定义一组没有方法体的方法。
基本语法:
type 接口名 interface {
method1(参数列表)返回值列表
method2(参数列表)返回值列表
...
}
要注意的是:
1.接口变量内不能包含变量
2.接口里的方法都没有方法体(即没有实现的方法)
3.接口的实现不用像其他语言一样显示的声明实现。只需一个变量含有接口类型中的所有方法(是所有方法)
4.因为不是显示的实现接口,那么如果两个不同名的接口有一样的方法,一个类型有他们一样的方法,那么也是实现了这两个接口
package main
import "fmt"
type Person interface {
Say()
run()
}
type Stundent struct {
Name string
Age int
}
func (s *Stundent) Say() {
fmt.Println(s.Name," say hello")
}
func (s *Stundent) run() {
fmt.Println(s.Name,"runing")
}
5.当有一个方法的接收的参数是一个接口类型的变量,那么实现了这个接口的变量都可以作为参数传入,注意:实现了接口的变量传参时要加 &符
package main
import "fmt"
type Usb interface {
Start()
Stop()
}
//Mp3 将接口两个方法都实现了
type Mp3 struct {
Name string
}
func (c *Mp3) Start() {
fmt.Println(c.Name,"start working")
}
func (c *Mp3) Stop() {
fmt.Println(c.Name,"stop work")
}
//Phone 没有将两个接口方法都实现
type Phone struct {
Name string
}
func (p *Phone) Start() {
fmt.Println(p.Name,"start working")
}
type Computer struct {
Name string
}
func (c *Computer)Working(u Usb) {
u.Start()
u.Stop()
}
func main() {
mp3 := Mp3{"mp3"}
computer := Computer{"computer"}
computer.Working(&mp3)
//phone := Phone{"phone"} //没有实现usb的两个方法
//computer.Working(&phone) //报错
}
6.接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量(实例)
package main
import "fmt"
type Ainterface interface {
Say()
}
type Person struct {
Name string
}
func(p Person)Say() {
fmt.Println(p.Name,"say hello")
}
func main() {
person := Person{"jack"}
var a Ainterface
a = person
a.Say()
}
7.能实现接口的不仅仅只有结构体类型,只要是自定义类型的变量实现了接口的方法,那么就实现了这个接口(同理,自定义类型也可以同时实现多个接口)
package main
import "fmt"
type Ainterface interface {
Say()
}
type integer int //自定义int类型
func(i integer)Say() {
fmt.Println("integer = ",i)
}
func main() {
var i integer = 10
var a Ainterface = i
a.Say()
}
8.接口与接口之间也可以继承(也可以多继承),当A接口继承了B接口和C接口,那么要实现A接口的话,那么就必须将B、C接口的方法也要全部实现(如下代码,如果注释掉D实例的一个方法,那么就会报错)
import "fmt"
type B interface {
Bsay()
}
type C interface {
Csay()
}
type Ainterface interface {
B
C
Asay()
}
type D struct {
}
func (d D) Asay() {
fmt.Println("d method Asay")
}
func (d D) Bsay() {
fmt.Println("d method Bsay")
}
func (d D) Csay() {
fmt.Println("d method Csay")
}
func main() {
d := D{}
var a Ainterface = d //将实例变量d赋值给A接口变量
a.Asay()
a.Bsay()
a.Csay()
}
9.interface类型默认是一个指针(引用类型),如果没有对interface初始化(赋初始值)就使用,那么就会输出nil
package main
import "fmt"
type B interface {
Bsay()
}
func main() {
var b B
fmt.Println(b) //没有进行初始化赋值
}
10.空接口(没有任何方法的接口),正因为没有任何方法,那么所有的类型都实现了空接口。即所有的类型都可以赋值给空接口变量(任意的数据类型变量都可以赋值给接口变量,而且可以任意数据类型变量切换赋值)
package main
import "fmt"
type B interface {
}
type Person struct {
Name string
}
func main() {
p:= Person{"jack"}
var b B = p //结构体类型
fmt.Println(b)
b = 18 //int类型
fmt.Println(b)
b = "爱我中华" //字符串
fmt.Println(b)
}