1.1.1. 一、接口的定义语法:

go语言的接口是interface 类型,可以定义一组方法,但是这些不需要实现。并且 interface 不能包含任何变量。语法如下:

type 接口名 interface {
    方法名1 (参数列表) 返回值列表
    方法名2 (参数列表) 返回值列表
}

任何自定义数据类型,就可以实现接口。但是某个类型实现了某个接口,是隐式的实现,并不需要特意指出来。只要实现了接口的所有方法,那么这个类型就实现了这个接口。

  • 示例如下:

定义一个User 接口,UserImpl 结构体实现了这个接口。Working 函数接收User 接口作为参数。

//定义一个接口,声明了两个没有实现的方法
type User interface {
    Add()
    Delete()
}

// 定义一个结构体,实现User接口
type UserImpl struct {
}
func (p UserImpl) Add() { //实现Add
    fmt.Println("增加。。。")
}
func (p UserImpl) Delete() { //实现Delete
    fmt.Println("删除。。。")
}

//定义一个函数,接口类型做参数。实现多肽
func Working(us User) {
    us.Add()
    us.Delete()
}
func main() {
    userImpl := UserImpl{}

    //调用方法,传递接口的实现
    Working(userImpl)
}

上面例子中:

1、User 接口和它的实现 UserImpl 没有任何的关系,是一个隐式的实现。

2、如果有User2 接口和User 接口一模一样,那UserImpl 也实现了User2 接口。一个struct可以实现无数个接口。

3、结构体必须全部实现接口的方法,才能是这个接口的实现。比如:上面例子中,如果给User 接口增加一个方法,那调用Working函数时编译就会报错。

1.1.2. 二、接口的注意事项。

1、接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量。

//定义一个接口,声明了两个没有实现的方法
type IUser interface {
    Add()
}
// 定义一个结构体,实现User接口
type UserImpl struct {
}
func (p UserImpl) Add() { //实现Add
    fmt.Println("增加。。。")
}

func main() {
    // 声明接口变量,指向实现类型的实例。
    var u IUser = UserImpl{}
}

var u IUser = UserImpl{}这里就是声明接口变量,指向实现类的实例

2、接口中所有的方法都没有方法体,即都是没有实现的方法。

3、在 Golang 中,一个自定义类型需要将某个接口的所有方法都实现,我们才说这个自定义类型实现了该接口。

4、一个自定义类型只有实现了某个接口,才能将该自定义类型的实例(变量)赋给接口类型。

5、任何自定义数据类型,就可以实现接口,不仅仅是结构体类型。(自定义数据类型用 type声明。比如:type MyInt int 就定义了一个MyInt 的数据类型)。实例如下:

//定义一个接口,声明了两个没有实现的方法
type IUser interface {
    Add()
}
type MyInt int

func (i MyInt) Add() { //实现Add
    fmt.Println("增加。。。")
}

1、自定义了一个数据类型 MyInt 。

2、MyInt 实现了IUser 接口的Add() 方法。所以MyInt 是IUser 接口的实现。

6、一个自定义类型可以实现多个接口。

7、Golang 接口中不能有任何变量。

type IUser interface {
    Name string // 编译报错
    Add()
}

8、interface 类型默认是一个指针(引用类型),如果没有对 interface 初始化就使用,那么会输出 nil。

type EmptyInterface interface {

}
func main() {
    var test EmptyInterface
    fmt.Println(test) //<nil>
}

9、空接口 interface{} 没有任何方法,所以所有类型都实现了空接口, 即我们可以把任何一个变量赋给空接口

实例:接收空接口作为参数,表示接收任意类型参数。

// 接收空接口做参数,表示接收任意类型参数
func test(p interface{})  {
    fmt.Println(p)
}
func main() {
    test("你好") // 你好
    test(123) // 123
}

也可以这样:

type EmptyInterface interface {

}
func test(p EmptyInterface)  {
    fmt.Println(p)
}
func main() {
    test("你好") // 你好
    test(123) // 123
}

还可以这样:interface{} 整体作为一个类型。相当于匿名的接口类型。

func main() {
    var testInte interface{} = 15
    testInte = "你好"
    fmt.Println(testInte)
}

1.1.3. 三、接口的继承。

接口的继承和struct的继承类似。在一个接口内,嵌入其他接口即可。

注意:一个接口(比如 C 接口)可以继承多个别的接口(比如 A、B 接口),这时如果要实现 C 接口,也必须将 A、B 接口的方法也全部实现。

继承实例如下:CInterface 接口继承了BInterface接口 和 AInterface接口。

type AInterface interface {
    TestA()
}
type BInterface interface {
    TestB()
}
type CInterface interface {
    AInterface //继承 AInterface 接口
    BInterface //继承 BInterface 接口
    TestC()
}

1.1.4. 四、指针类型实现接口。

type IUser interface {
    Add()
}
type UserImpl struct {
}
// UserImpl的指针类型实现了Add方法
func (p *UserImpl) Add() {
    fmt.Println("增加。。。")
}

func main() {
    // 这里直接把指针给接口,因为是UserImpl的指针类型实现了IUser接口。
    var u IUser = &UserImpl{}
    u.Add()
}

说明:这里是UserImpl的指针类型实现了IUser接口。使用的时候直接把指针赋值给接口即可:var u IUser = &UserImpl{}

results matching ""

    No results matching ""