Go 语言没有传统的“类”和“继承”概念,而是通过 结构体 (Struct) 来封装数据,通过 接口 (Interface) 来定义行为。这种组合式设计(Composition over Inheritance)让代码更加灵活和解耦。

示例代码

 1package main
 2
 3import "fmt"
 4
 5// 定义一个接口:只要实现了 Speak 方法的类型,都满足这个接口
 6type Speaker interface {
 7    Speak() string
 8}
 9
10// 定义结构体 Dog
11type Dog struct {
12    Name string
13}
14
15// Dog 实现 Speaker 接口
16// 注意:Go 中没有 implements 关键字,这是隐式实现的
17func (d Dog) Speak() string {
18    return "Woof!"
19}
20
21// 定义结构体 Cat
22type Cat struct {
23    Name string
24}
25
26// Cat 实现 Speaker 接口
27func (c Cat) Speak() string {
28    return "Meow!"
29}
30
31// 多态演示:接收任何 Speaker
32func introduce(s Speaker) {
33    fmt.Println(s.Speak())
34}
35
36func main() {
37    d := Dog{Name: "Buddy"}
38    c := Cat{Name: "Kitty"}
39
40    introduce(d) // Woof!
41    introduce(c) // Meow!
42
43    // 接口类型断言
44    var s Speaker = d
45    if dog, ok := s.(Dog); ok {
46        fmt.Printf("It's a dog named %s\n", dog.Name)
47    }
48}

关键点解释

结构体 (Struct)

  • 用户自定义的数据类型,是一组字段的集合。
  • 匿名嵌入:可以在结构体中嵌入另一个结构体(不给字段名),从而直接访问其字段和方法,实现类似“继承”的效果。
1type Animal struct { Age int }
2type Dog struct {
3    Animal // 嵌入
4    Name string
5}
6// d := Dog{}
7// d.Age = 10 // 直接访问

接口 (Interface)

  • 鸭子类型 (Duck Typing):如果一只鸟走起来像鸭子,叫起来像鸭子,那它就是鸭子。在 Go 中,只要一个类型实现了接口要求的所有方法,它就自动实现了该接口。
  • 空接口 interface{}:不包含任何方法,因此任何类型都实现了空接口。类似于 Java 的 Object,常用于泛型容器。

类型断言

  • value, ok := interfaceVar.(Type):检查接口变量是否保存了特定类型的值。建议总是检查 ok 以避免 panic。

小结

结构体用于组织数据,接口用于抽象行为。掌握 Go 的隐式接口实现和组合模式,是编写地道 Go 代码的关键。

练习题

  1. 定义一个 Shape 接口,包含 Area()Perimeter() 方法。
  2. 实现 Rectangle (矩形) 和 Circle (圆形) 结构体,并实现上述接口。

相关阅读