
go 语言不支持传统面向对象的继承和构造函数,但可通过结构体嵌入(embedding)复用已有类型的方法与字段,从而实现类似“扩展”的效果。
go 语言不支持传统面向对象的继承和构造函数,但可通过结构体嵌入(embedding)复用已有类型的方法与字段,从而实现类似“扩展”的效果。
在 Go 中,没有 class、extends 或 constructor 等概念,取而代之的是组合优于继承的设计哲学。当你希望让 Square 复用 Rectangle 的 area() 方法时,最自然、最符合 Go 风格的方式是使用匿名字段嵌入(embedding):
type Rectangle struct {
h, w int
}
func (r *Rectangle) area() int {
return r.w * r.h
}
type Square struct {
Rectangle // 嵌入 Rectangle,自动获得其字段和方法
}
此时,Square 实例可以直接调用 area() 方法:
s := Square{Rectangle{5, 5}}
fmt.Println(s.area()) // 输出:25
⚠️ 注意事项:
- 嵌入后,
Square并非Rectangle的子类,而是拥有Rectangle的全部公开字段和方法(即“has-a”,而非“is-a”); -
Square无法在area()中感知自身是否为正方形——因为该方法只作用于嵌入的Rectangle字段,它看不到Square自身可能新增的字段或逻辑; - 若需正方形专属行为(如仅设置边长),可为
Square添加专属构造函数(Go 中惯用的工厂函数):
func NewSquare(side int) Square {
return Square{Rectangle{h: side, w: side}}
}
// 使用示例
s := NewSquare(7)
fmt.Println(s.area()) // 49
✅ 总结:Go 不提供继承,但嵌入 + 组合 + 方法提升(promoted methods)提供了更灵活、更显式的代码复用机制。与其试图“模拟继承”,不如专注设计清晰的接口与职责分明的结构体——这正是 Go 简洁性与工程可靠性的核心所在。










