前言
大家好,这里是程序员阿亮,这几天也是在找实习的路上,有一家公司约面说使用的后端语言是Golang,我也是学过一点Go的,但是很久没写了,所以就翻出来复习一下,顺便手痒痒想记录一下博客。
在编程世界中,提到"面向对象(OOP)",大多数人的第一反应是:类(Class)、继承(Inheritance)和多态(Polymorphism)。如果你带着 Java 或 C++ 的思维进入 Go 语言的世界,你可能会感到困惑:"为什么没有 class 关键字?""如何实现继承?""没有 extends我该怎么办?"
事实上,Go 是一门面向对象的语言 ,但它采用了完全不同的设计哲学。Go 抛弃了复杂的类继承体系,转而拥抱组合(Composition)和接口(Interfaces)。
今天,我们就来聊聊 Go 是如何以"非传统"的方式实现 OOP 的三大特性的。
一、封装:从 Class 到 Struct
在 Go 中,没有 class,只有 struct(结构体)。数据和行为(方法)是分开定义的,但通过 Receiver(接收者) 关联在一起。
1.1 简单的例子:
Go
package main
import "fmt"
// User 定义数据结构
type User struct {
ID int
Name string
}
// GetInfo 是关联到 User 结构体的方法, 前面的括号里面的User就是我们结构体和函数关联的体现
func (u User) GetInfo() string {
return fmt.Sprintf("ID: %d, Name: %s", u.ID, u.Name)
}
func main() {
u := User{ID: 1, Name: "Alice"}
fmt.Println(u.GetInfo())
}
访问控制(可见性)
Go 没有 public、private 关键字。它使用一种极简的规则:
-
大写字母开头:导出(Public),其他包可见。
-
小写字母开头:不导出(Private),仅限当前包可见。
这种基于命名的封装方式,让代码更加简洁易读。
二、继承 vs. 组合:逻辑的复用
这是 Go 与传统 OOP 最大的区别。Go 坚信 "组合优于继承" 。Go 不支持 class Child extends Parent,而是使用 Struct Embedding(结构体嵌套/嵌入)
结构体嵌入示例
Go
type Animal struct {
Name string
}
func (a Animal) Eat() {
fmt.Println(a.Name, "is eating...")
}
type Dog struct {
Animal // 嵌入了 Animal,Dog 自动拥有了 Animal 的属性和方法
Breed string
}
func main() {
d := Dog{
Animal: Animal{Name: "Buddy"},
Breed: "Golden Retriever",
}
d.Eat() // 直接调用嵌入类型的方法
}
为什么这样做更好?
传统的类继承容易导致"脆弱基类问题"和复杂的深度层级。Go 的组合模式更加扁平、松耦合,让代码维护变得简单。
三、多态:非侵入式接口
Go 的接口(Interface)是其 OOP 体系中的灵魂。与 Java 不同,Go 的接口实现是**隐式(Implicit)**的。
只要你叫起来像鸭子,你就是鸭子
在 Java 中,你必须显式声明 implements Shape。在 Go 中,只要一个类型实现了接口定义的全部方法 ,它就自动实现了该接口。
Go
// 定义接口
type Speaker interface {
Speak() string
}
type Cat struct{}
func (c Cat) Speak() string { return "Meow" }
type Robot struct{}
func (r Robot) Speak() string { return "Beep Boop" }
// 这是一个多态函数
func MakeItSpeak(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
c := Cat{}
r := Robot{}
MakeItSpeak(c) // 输出: Meow
MakeItSpeak(r) // 输出: Beep Boop
}
非侵入式接口的好处:
-
解耦:实现者不需要知道接口的存在,可以在不修改原有代码的基础上增加接口。
-
易于测试:通过定义接口,可以非常轻松地注入 Mock 对象进行单元测试。
总结
实际上会发现Go的语法相对于Java是非常非常简洁的,这种简洁的语法其实很多我认为是可以提高我们代码的可读性,在很多大厂如字节等,都在使用Golang
保持结构体简单,尽量定义小而精的接口(通常只有一个方法),你会发现 Go 的开发效率和运行效率会让你惊喜。

