Go语言入门17:接口
Table of Contents
Go 语言入门基础学习笔记之 Go 语言的接口
接口
Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何结构体只要拥有了这些成员方法,我们就说这个结构体实现了这个接口。
本质上接口是一个指针,指向所包含的函数列表。因此接口也是一个引用数据类型,在函数中直接传递原来的变量。
接口可以让我们将不同的类型绑定到一组公共的方法上,从而实现多态和灵活的设计。
Go 语言中的接口是隐式实现的,也就是说,如果一个类型实现了一个接口定义的所有方法,那么它就自动地实现了该接口。因此,我们可以通过将接口作为参数来实现对不同类型的调用,从而实现多态。
我们可以通过一下代码来检查这个类型是否实现了接口:
var _ Interface = (*Type)(nil)
如果没有实现,则会抛出一个具体的错误,方便定位出错的地方。
接口是一组方法的集合,与结构体不同的是,接口中不放成员变量,只放置方法。
实现接口中定义的所有方法,是实现(成为)这个接口的必须条件。
如果定义了一个空接口,则任何类型都实现(成为)了这个接口,相对于其他语言中的
object
。Go 语言自带了一个空接口类型
any
,任何数据类型都属于一种any
/* 定义接口 */
type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
method_namen [return_type]
}
/* 定义结构体 */
type struct_name struct {
/* variables */
}
/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {
/* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
/* 方法实现*/
}
实例 1:
package main
import "fmt"
// 定义 Animal 接口,包含两个方法
type Animal interface {
Speak() string // 动物发声方法,返回一个字符串
Eat(food string) string // 动物吃东西方法,接受食物字符串并返回一个字符串
}
// 定义 Dog 结构体,表示狗
type Dog struct {
Name string // 狗的名字
}
// 定义 Cat 结构体,表示猫
type Cat struct {
Name string // 猫的名字
}
// 实现 Animal 接口的方法
// Dog 实现 Animal 接口的 Speak 方法
func (d Dog) Speak() string {
return "Woof! My name is " + d.Name // 返回狗的叫声和名字
}
// Dog 实现 Animal 接口的 Eat 方法
func (d Dog) Eat(food string) string {
return d.Name + " is eating " + food // 返回狗正在吃的食物
}
// Cat 实现 Animal 接口的 Speak 方法
func (c Cat) Speak() string {
return "Meow! My name is " + c.Name // 返回猫的叫声和名字
}
// Cat 实现 Animal 接口的 Eat 方法
func (c Cat) Eat(food string) string {
return c.Name + " is eating " + food // 返回猫正在吃的食物
}
// describeAnimal 函数展示 Animal 接口的特性
func describeAnimal(a Animal) {
fmt.Println(a.Speak()) // 调用 Speak 方法,并打印返回值
fmt.Println(a.Eat("food")) // 调用 Eat 方法,并打印返回值,传入字符串 "food"
}
func main() {
// 创建一个 Dog 实例
dog := Dog{Name: "Buddy"}
// 创建一个 Cat 实例
cat := Cat{Name: "Whiskers"}
// 调用 describeAnimal 函数,展示狗的行为
describeAnimal(dog)
// 调用 describeAnimal 函数,展示猫的行为
describeAnimal(cat)
}
// 输出结果
Woof! My name is Buddy
Buddy is eating food
Meow! My name is Whiskers
Whiskers is eating food
代码说明
- 接口定义:
Animal
接口定义了两个方法Speak()
和Eat(string)
,这两个方法是Animal
接口的行为特点。
- 结构体定义:
Dog
和Cat
结构体分别代表不同的动物,它们都有一个Name
字段。
- 接口方法的实现:
Dog
和Cat
都实现了Animal
接口的方法。这展示了多态性,即不同的类型可以通过相同的接口进行操作。
- 接口展示:
describeAnimal
函数接受一个Animal
类型的参数,可以接收实现了Animal
接口的任何类型,展示了接口的灵活性和可扩展性。
- 主函数:
- 在
main
函数中,创建了Dog
和Cat
的实例,并调用describeAnimal
函数,展示了不同动物的行为。
- 在
实例 2:
package main
import "fmt"
// 定义一个 Shape 接口,包含一个计算面积的方法
type Shape interface {
area() float64 // 声明 area 方法,返回值为 float64
}
// 定义一个 Rectangle 结构体,表示矩形
type Rectangle struct {
width float64 // 矩形的宽度
height float64 // 矩形的高度
}
// 为 Rectangle 结构体实现 area 方法
func (r Rectangle) area() float64 {
return r.width * r.height // 返回矩形的面积
}
// 定义一个 Circle 结构体,表示圆形
type Circle struct {
radius float64 // 圆形的半径
}
// 为 Circle 结构体实现 area 方法
func (c Circle) area() float64 {
return 3.14 * c.radius * c.radius // 返回圆形的面积,使用 π ≈ 3.14
}
func main() {
var s Shape // 声明一个 Shape 类型的变量 s
// 将 s 指向一个 Rectangle 实例
s = Rectangle{width: 10, height: 5}
// 调用 area 方法并打印矩形的面积
fmt.Printf("矩形面积: %f\n", s.area())
// 将 s 指向一个 Circle 实例
s = Circle{radius: 3}
// 调用 area 方法并打印圆形的面积
fmt.Printf("圆形面积: %f\n", s.area())
}
// 输出结果
矩形面积: 50.000000
圆形面积: 28.260000
以上实例中,我们定义了一个 Shape
接口,它定义了一个方法 area()
,该方法返回一个 float64
类型的面积值。然后,我们定义了两个结构体 Rectangle
和 Circle
,它们分别实现了 Shape
接口的 area()
方法。在 main()
函数中,我们首先定义了一个 Shape
类型的变量 s
,然后分别将 Rectangle
和 Circle
类型的实例赋值给它,并通过 area()
方法计算它们的面积并打印出来。
需要注意的是,接口类型变量可以存储任何实现了该接口的类型的值。在示例中,我们将
Rectangle
和Circle
类型的实例都赋值给了Shape
类型的变量s
,并通过area()
方法调用它们的面积计算方法。
参考课程: