Go 语言编程基础:面向对象编程
1. 类型系统
Go 语言虽然不完全是面向对象的语言,但它仍然提供了强大的类型系统和面向对象的编程方式。
1.1 为类型添加方法
-
在 Go 中可以为自定义的类型添加方法,方法与函数类似,但方法会关联到一个接收者(Receiver)。
-
示例:
type Person struct { name string age int } // 为 Person 类型添加方法 func (p Person) greet() string { return "Hello, my name is " + p.name } func main() { person := Person{name: "Alice", age: 30} fmt.Println(person.greet()) }
-
接收者类型可以是值类型或指针类型。如果你希望修改接收者的值,应该使用指针类型。
2. 初始化
2.1 类型初始化
-
Go 语言中的类型可以通过结构体字面量或工厂函数进行初始化。
-
示例:
type Person struct { name string age int } // 初始化 Person 类型 func main() { person := Person{name: "Bob", age: 25} fmt.Println(person) }
3. 匿名组合
Go 没有传统的类继承机制,但它提供了组合,可以通过嵌套类型实现类似继承的功能。
3.1 类型组合
-
使用组合可以让一个类型包含另一个类型的字段和方法。
-
示例:
type Address struct { city string state string } type Person struct { name string age int Address // 匿名组合 Address 类型 } func main() { person := Person{ name: "John", age: 28, Address: Address{ city: "San Francisco", state: "CA", }, } fmt.Println(person.name, person.city) // 通过组合访问 Address 的字段 }
4. 可见性
Go 语言使用首字母大小写来决定符号(类型、方法、字段、变量等)的可见性:
- 首字母大写:对包外可见,即可以导出。
- 首字母小写:仅在当前包内可见。
4.1 访问控制
-
导出和未导出的规则可以应用于类型、函数、字段、方法等。
-
示例:
type Person struct { Name string // 公有字段 age int // 私有字段 } func (p Person) getAge() int { return p.age // 私有字段通过方法访问 }
5. 接口
接口是 Go 语言中实现多态和动态行为的核心机制。
5.1 其他语言的接口
- 在 C++ 和 Java 中,接口需要通过显式的继承关系进行实现。
- Go 语言采用非侵入式接口,即类型无需显式声明实现某个接口,只要实现了接口中要求的所有方法,该类型就被认为实现了接口。
5.2 非侵入式接口
-
Go 的接口无需显示声明类型与接口之间的关系。
-
示例:
type Speaker interface { Speak() string } type Dog struct { name string } func (d Dog) Speak() string { return "Woof! My name is " + d.name } func main() { var s Speaker s = Dog{name: "Buddy"} fmt.Println(s.Speak()) }
5.3 接口赋值
-
类型实现了某个接口后,接口类型的变量可以持有该类型的值:
var speaker Speaker speaker = Dog{name: "Buddy"} // Dog 实现了 Speaker 接口
6. 完整示例
一个包含接口、类型组合和方法的完整示例:
package main
import "fmt"
// 定义接口
type Speaker interface {
Speak() string
}
// 定义 Dog 类型并实现接口
type Dog struct {
name string
}
func (d Dog) Speak() string {
return "Woof! My name is " + d.name
}
// 定义 Person 类型并组合 Address 类型
type Address struct {
city string
state string
}
type Person struct {
name string
age int
Address // 匿名组合
}
func main() {
// 实例化 Dog 并调用接口方法
var s Speaker
s = Dog{name: "Max"}
fmt.Println(s.Speak())
// 实例化 Person 并使用组合字段
person := Person{
name: "Alice",
age: 30,
Address: Address{
city: "New York",
state: "NY",
},
}
fmt.Println(person.name, person.city)
}
7. 小结
- 类型和方法:Go 可以为类型定义方法,类似于面向对象语言的类。
- 组合:通过嵌套类型实现类似继承的功能。
- 接口:Go 使用非侵入式接口,类型无需显式声明实现接口,只要实现了接口的方法即可。
- 访问控制:通过首字母大小写控制可见性,大写为公开,小写为私有。