Go中(interface) 接口实现与多态

164 阅读2分钟

1. 接口实现

在 Go 语言中,接口实现是通过实现接口中的所有方法来完成的。

如果一个类型定义了与某个接口中所有方法同名、同参数、同返回类型的方法,那么这个类型就隐式地实现了该接口。

Go语言中的接口实现与其他语言有所区别,Go的接口实现是一种隐式的操作,而不是使用特定的关键字来阐述

下面是一个示例代码:

package main

import "fmt"

type Animal interface {
    Speak() string
}

type Cat struct{}

func (c Cat) Speak() string {
    return "Meow!"
}

func main() {
    var animal Animal
    animal = Cat{}
    fmt.Println(animal.Speak()) // Output: Meow!
}


在上面的示例代码中,我们定义了一个 Animal 接口,它只有一个方法 Speak。然后我们定义了一个 Cat 类型,并为其实现了 Animal 接口中的 Speak 方法。最后,在 main 函数中,我们创建了一个 Animal 类型的变量 animal,并将其赋值为一个 Cat 变量。由于 Cat 实现了 Animal 接口中的 Speak 方法,因此可以将 Cat 变量赋值给 Animal 类型的变量。最终输出结果是 Meow!

需要注意的是,Go 语言中的接口是隐式的,也就是说,一个类型无需显式声明它实现了某个接口。只要该类型实现了接口中的所有方法,就被认为是实现了该接口。

2. 多态

在Go语言中,因为没有继承,所以也无法实现传统意义上的多态机制。但是,由于Go语言中的接口可以作为一种契约来描述对象的行为,可以通过接口实现类似多态的效果

package main

import "fmt"

type Animal interface {
    Speak() string
}

type Dog struct{}

func (d Dog) Speak() string {
    return "Woof!"
}

type Cat struct{}

func (c Cat) Speak() string {
    return "Meow!"
}

func main() {
    animals := []Animal{Dog{}, Cat{}}

    for _, animal := range animals {
        fmt.Println(animal.Speak())
    }
}

Woof!
Meow!

这段代码是鸭子类型吗?

Go语言本身并没有鸭子类型这一概念,它是一个动态类型语言的概念。在动态类型语言中,方法的调用会依据对象的实际类型来确定,而不是依据对象的声明类型来确定。因此,在这种语言中,只要某个对象满足某个方法的签名,那么就可以将其作为参数传递给该方法。

但是,Go语言是一门静态类型语言,方法的调用会依据结构体类型的声明来确定。Go语言中的接口虽然可以实现类似于鸭子类型的效果,但这并不代表Go语言本身支持鸭子类型。由于Go语言的类型系统相对较为严格,因此在使用接口时需要注意接口的定义和实现是否一致。

总之,尽管Go语言中没有鸭子类型这一概念,但是通过接口和结构体类型的组合使用,也可以实现类似于鸭子类型的效果。