
go 不支持传统面向对象的继承,但可通过结构体嵌入(embedding)让 square 复用 rectangle 的 area 方法,实现代码复用与组合式设计。
go 不支持传统面向对象的继承,但可通过结构体嵌入(embedding)让 square 复用 rectangle 的 area 方法,实现代码复用与组合式设计。
在 Go 中,没有“构造函数”概念,也没有类继承机制,取而代之的是组合优于继承的设计哲学。要让 Square 复用 Rectangle 的 area() 方法,最自然、符合 Go 语言惯用法的方式是使用匿名字段嵌入(embedding)。
下面是一个完整、可运行的示例:
package main
import "fmt"
type Rectangle struct {
h, w int
}
func (r *Rectangle) area() int {
return r.w * r.h
}
// Square 嵌入 Rectangle,获得其字段和方法
type Square struct {
Rectangle
}
func main() {
// 初始化 Square:可直接设置嵌入字段
s := Square{Rectangle{h: 5, w: 5}}
fmt.Println("Square area:", s.area()) // 输出:25
// 或更简洁地(因 Rectangle 是匿名字段,可提升字段)
s2 := Square{Rectangle{5, 5}}
fmt.Println("Square area (shorthand):", s2.area())
// 甚至可直接赋值提升后的字段(Go 自动“提升”嵌入字段名)
s3 := Square{}
s3.h, s3.w = 7, 7
fmt.Println("Square area (field promotion):", s3.area())
}✅ 关键要点说明:
-
Square中的Rectangle是匿名字段,因此Square实例自动拥有Rectangle的所有导出字段(h,w)和方法(area); - Go 会将嵌入类型的方法“提升”(promoted)到外层结构体,所以
s.area()可直接调用; - 字段也支持提升:
s.h和s.w是合法的,等价于s.Rectangle.h/s.Rectangle.w; - 注意:嵌入不是继承——
Square并不“是”一个Rectangle,而是“包含”一个Rectangle;它无法重写或覆盖area(),也不能访问仅属于Square自身的新字段(如有)——因为area()的接收者是*Rectangle,其作用域仅限于Rectangle的字段。
⚠️ 注意事项:
- 若后续需为
Square添加专属行为(例如isPerfect()判断是否为完美正方形),应定义在Square类型上,而非试图修改Rectangle; - 避免过度嵌入多层结构,否则会降低可读性与可维护性;
- 嵌入适用于“has-a”关系(Square has a Rectangle),而非“is-a”语义——这正是 Go 鼓励的清晰、显式的组合风格。
总结:虽然 Go 没有构造函数和继承,但通过嵌入,你能以更轻量、更可控的方式复用逻辑。这是 Go 强调的“少即是多”(Less is more)与“组合优于继承”的典型实践。

















