Go语言如何在工厂模式下实现结构体继承?
Go工厂模式下实现结构体的“继承”(基于组合)
Go语言没有传统面向对象的类继承机制,我们通常通过结构体嵌入(组合)来实现类似继承的属性与方法复用,结合工厂模式的改造方式如下:
原有代码回顾
假设你的原有代码结构如下:
student.go
package main // 包私有结构体,仅当前包可访问 type student struct { name string score int } // 工厂函数:标准化创建student实例 func NewStudent(name string, score int) *student { return &student{ name: name, score: score, } } // student的方法:获取成绩 func (s *student) GetScore() int { return s.score }
main.go
package main import "fmt" func main() { stu := NewStudent("张三", 85) fmt.Println("学生成绩:", stu.GetScore()) }
改造实现“继承”
我们以创建graduateStudent(研究生)为例,复用student的属性和方法,同时扩展自身特性:
修改student.go,新增研究生相关代码
// 在student.go中添加以下内容 // 研究生结构体:嵌入student指针,复用其属性与方法 type graduateStudent struct { *student // 嵌入父结构体指针 thesisTopic string // 研究生独有的属性:论文题目 } // 研究生的工厂函数:调用student的工厂函数完成嵌入部分的初始化 func NewGraduateStudent(name string, score int, thesisTopic string) *graduateStudent { return &graduateStudent{ student: NewStudent(name, score), // 借助父类工厂保证实例化逻辑统一 thesisTopic: thesisTopic, } } // 研究生独有的方法:获取论文题目 func (g *graduateStudent) GetThesisTopic() string { return g.thesisTopic } // 可选:重写GetScore方法,实现自定义逻辑 func (g *graduateStudent) GetScore() int { // 示例:研究生成绩额外加5分加权 return g.student.GetScore() + 5 }
修改main.go测试效果
package main import "fmt" func main() { // 创建普通学生实例 stu := NewStudent("张三", 85) fmt.Println("普通学生成绩:", stu.GetScore()) // 创建研究生实例 gradStu := NewGraduateStudent("李四", 88, "Go语言并发模型研究") // 直接访问嵌入结构体的属性 fmt.Println("研究生姓名:", gradStu.name) // 调用父结构体的原始方法 fmt.Println("研究生原始成绩:", gradStu.student.GetScore()) // 调用重写后的方法 fmt.Println("研究生加权成绩:", gradStu.GetScore()) // 调用自身独有的方法 fmt.Println("研究生论文题目:", gradStu.GetThesisTopic()) }
核心要点说明
- 结构体嵌入是Go的“继承”实现方式:通过嵌入另一个结构体(或指针),子类结构体可以直接使用父结构体的所有属性和方法
- 工厂模式的兼容:子类工厂函数可以调用父类工厂函数来初始化嵌入部分,保证父类实例的创建逻辑被复用,避免重复代码
- 方法重写与多态:子类可以定义同名方法覆盖父类的方法,实现自定义逻辑;调用时优先执行子类的方法
- 包访问权限注意:如果父结构体是小写的包私有类型,只能在同一个包内实现嵌入;若需要跨包复用,需将结构体、工厂函数、方法改为大写(公开访问)
内容的提问来源于stack exchange,提问作者Wang Li
相关产品推荐
相关产品推荐

