01介绍
Golang 语言是面向对象语言吗?Golang 语言官方的回答是 Yes and no。什么意思呢?Golang 语言是面向对象语言,Golang 语言也不是面向对象语言。
虽然 Golang 语言有类(struct)和方法(method),支持面向对象的编程风格,我们可以使用 Golang 语言的 struct 实现面向对象的封装特性,但是 Golang 语言没有面向对象的继承特性,Golang 语言可以使用组合实现“继承”。
Golang 语言中的 interface 也和其他语言中的接口实现方式不同,Golang 语言中的接口实现方式是鸭子类型(duck type)。
封装,继承和多态是区分编程语言是否是面向对象编程语言的三个重要特性。本文我们通过一些简单易懂的示例代码介绍一下 Golang 语言的面向对象编程风格。
02封装
面向对象的封装特性,其他面向对象语言是使用 class 定义一个类,然后在类中定义属性和方法。在 Golang 语言中,没有类 class 的概念,它是使用结构体 struct 替代类 class,struct 中可以包含零个或多个变量,然后可以使用 method 和 struct 绑定实现方法,用来替代其他语言中 class 中的属性和方法。
关于 method 绑定的 struct(接收者)是值类型和指针类型之间的区别,我们在之前的文章中介绍过,在此不再赘述。
- type Employee struct {
- Name string
- Gender string
- Age uint8
- Salary uint
- }
- func (e Employee) Information () string {
- return fmt.Sprintf("Name:%s Gender:%s Age:%d Salary:%d", e.Name, e.Gender, e.Age, e.Salary)
- }
阅读上面这段代码,我们定义了一个命名是 Employee 的 struct,包含 4 个成员变量,并且定义一个 Information 方法,绑定到命名是 Employee 的 struct 上。
03继承 组合
面向对象的继承特性,在 Golang 语言中并不支持,但是可以使用组合的方式实现“继承”。
- type User struct {
- ID uint64
- Name string
- Score uint64
- }
- type Member struct {
- User
- Level uint8
- }
- func (u User) Information () string {
- return fmt.Sprintf("ID:%d Name:%s Score:%d", u.ID, u.Name, u.Score)
- }
阅读上面这段代码,我们定义了一个命名为 User 的 struct,它包含 3 个成员变量,然后定一个一个命名为 Member 的 struct,它包含 2 个成员变量,其中一个成员变量是嵌入的 User,通过组合的方式,类型 Member 就“继承”了类型 User 的属性(成员变量)和方法。
04多态
Golang 语言中也有接口 interface,它的 interface 的实现方式是 duck type,它不需要像其他面向对象编程语言那样,使用关键字 implements 显式声明,而是只需要类型通过实现接口中的所有方法来实现接口。
- type MemberRights interface {
- Information () string
- }
- type BronzeMember struct {
- Discount uint8
- }
- type SilverMember struct {
- Discount uint8
- }
- type GoldMember struct {
- Discount uint8
- }
- func (b *BronzeMember) Information () string {
- return fmt.Sprintf("Discount:%d", b.Discount)
- }
- func (s *SilverMember) Information () string {
- return fmt.Sprintf("Discount:%d", s.Discount)
- }
- func (g *GoldMember) Information () string {
- return fmt.Sprintf("Discount:%d", g.Discount)
- }
- func Price (m MemberRights) {
- fmt.Println(m.Information())
- }
- func main () {
- b := &BronzeMember{Discount: 9}
- Price(b)
- s := &SilverMember{8}
- Price(s)
- g := new(GoldMember)
- g.Discount = 7
- Price(g)
- }
阅读上面这段代码,我们定义一个命名为 MemberRights 的接口,包含一个方法 Information () string,然后定义了三个 struct,命名分别是 BronzeMember,SilverMember 和 GoldMember,并且实现了 Information () string 方法。
我们还定义了一个函数 Price,接收一个 MemberRights 接口类型的参数。我们在 main 函数中调用 Price 函数,并分别传入我们定义的三个实现了 MemberRights 接口包含的方法 Information () string 的变量作为 Price 函数的参数。因为 Price 函数的参数是接口类型,所以我们需要传入指针类型的变量,我们还特意通过三种不同的方式声明指针类型的变量。
05总结
本文我们介绍了 Golang 语言是否是面向对象编程风格的语言,并给出了 Golang 语言官方的回答和解释。然后使用示例代码介绍了 Golang 语言的面向对象编程风格。
需要注意的是 Golang 语言中使用命名首字母大小写区分私有和公有,私有和公有属性在 Golang 语言中也叫可导出和非可导出。
本文转载自微信公众号「Golang语言开发栈」,可以通过以下二维码关注。转载本文请联系Golang语言开发栈公众号。