封装:控制数据访问权限
package main
import "fmt"
type Person struct {
name string // 私有字段
Age int // 公有字段
}
// 设置私有字段的方法
func (p *Person) SetName(name string) {
p.name = name
}
// 获取私有字段的方法
func (p *Person) GetName() string {
return p.name
}
// 设置公有字段的方法
func (p *Person) SetAge(age int) {
p.Age = age
}
func main() {
p := Person{Age: 25}
// 通过方法访问和修改字段
p.SetName("Alice")
p.SetAge(30)
fmt.Println("Name:", p.GetName()) // Name: Alice
fmt.Println("Age:", p.Age) // Age: 30
// 直接访问私有字段会导致编译错误
// fmt.Println(p.name) // 错误:p.name未定义
}
继承:通过结构体嵌套实现
1. 简单继承示例
package main
import "fmt"
// 父结构体
type Animal struct {
Name string
}
// 父结构体方法
func (a *Animal) Speak() {
fmt.Println(a.Name + " makes a sound.")
}
// 子结构体
type Dog struct {
Animal // 嵌入父结构体
}
func main() {
dog := Dog{Animal{Name: "Buddy"}}
dog.Speak() // 输出: Buddy makes a sound.
}
2. 方法重写示例
package main
import "fmt"
type Animal struct {
Name string
}
func (a *Animal) Speak() {
fmt.Println(a.Name + " makes a sound.")
}
type Dog struct {
Animal
}
// 重写父结构体方法
func (d *Dog) Speak() {
fmt.Println(d.Name + " barks.")
}
func main() {
dog := Dog{Animal{Name: "Buddy"}}
dog.Speak() // 输出: Buddy barks. (重写后的方法)
dog.Animal.Speak() // 输出: Buddy makes a sound. (原始父类方法)
}
多态:通过接口实现
1. 简单多态示例
package main
import "fmt"
// 接口定义
type Speaker interface {
Speak() string
}
// Dog类型实现接口
type Dog struct{}
func (d Dog) Speak() string {
return "Woof!"
}
// Cat类型实现接口
type Cat struct{}
func (c Cat) Speak() string {
return "Meow!"
}
// 接收接口类型参数的函数
func Introduce(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
Introduce(Dog{}) // 输出: Woof!
Introduce(Cat{}) // 输出: Meow!
}
2. 使用接口统一处理不同形状
package main
import "fmt"
// 形状接口
type Shape interface {
Area() float64
}
// 矩形类型
type Rectangle struct {
Width, Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// 圆形类型
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
// 通用函数处理不同形状
func PrintArea(s Shape) {
fmt.Printf("面积: %.2f\n", s.Area())
}
func main() {
PrintArea(Rectangle{Width: 5, Height: 3}) // 面积: 15.00
PrintArea(Circle{Radius: 4}) // 面积: 50.24
}
3. 需要修改内部状态的多态实现
package main
import "fmt"
// 定义接口
type Animal interface {
Speak() string
SetName(name string)
}
// Dog实现
type Dog struct {
name string
}
func (d *Dog) Speak() string {
return "Woof! My name is " + d.name
}
func (d *Dog) SetName(name string) {
d.name = name
}
func main() {
animals := []Animal{
&Dog{name: "Rex"},
&Dog{name: "Buddy"},
}
for _, animal := range animals {
fmt.Println(animal.Speak())
}
// 修改其中一个动物的名字
animals[0].SetName("Max")
fmt.Println(animals[0].Speak()) // Woof! My name is Max
}
接口继承
package main
import "fmt"
// 基础接口
type Animal interface {
Speak() string
}
// 继承接口
type Mammal interface {
Animal // 嵌入Animal接口
Move() string
}
// Dog实现所有接口方法
type Dog struct{}
func (d Dog) Speak() string {
return "Woof!"
}
func (d Dog) Move() string {
return "Runs on four legs"
}
func main() {
var dog Dog
// 使用Mammal接口
var mammal Mammal = dog
fmt.Println("哺乳动物:", mammal.Speak(), mammal.Move())
// 也可以使用基础接口
var animal Animal = dog
fmt.Println("动物:", animal.Speak())
}
Go面向对象关键点总结
封装
通过首字母大小写控制访问权限
小写字母开头的字段/方法为私有
大写字母开头的字段/方法为公有
继承
使用结构体嵌套实现继承
子结构体自动获得父结构体的所有字段和方法
可以重写父结构体的方法
多态
通过接口实现多态行为
不同类型可以实现相同的接口
以接口为参数的函数可以处理不同类型的值
最佳实践
需要修改状态时使用指针接收者
只读操作可以使用值接收者
优先使用接口定义行为,而不是具体类型
接口嵌套可以实现接口继承
Go语言的面向对象实现采用了独特的组合而非继承的方式,通过接口实现多态,通过结构体嵌入实现代码复用,既保持了类型系统的简洁性,又提供了强大的抽象能力。