go 面向对象
前言
在编程领域中,面向对象编程(OOP)是一种广泛使用的编程范式,它通过将数据和操作数据的函数封装成对象,以提高代码的可读性、可维护性和复用性。
Go 语言是一种静态类型、编译型的开源语言,其在语法上并不直接支持面向对象编程,但它提供了一种独特的方式来实现面向对象编程的一些核心理念,如封装、继承和多态。
在这篇文章中,我将探讨如何在 Go 语言中实现面向对象编程,展示一下如何通过 Go 语言的特性来实现面向对象编程。
面向对象思想
面向对象一般是跟面向过程相比较的,网上对这两个概念的介绍还是比较详细的,这里就简单的讲这两个概念分别表示什么。
面向过程,表示我们在编程时,解决一个问题会将其分成多个步骤,然后依次去实现这些步骤来达成目的。
面向对象,表示我们在编程时,会先将一个个事务抽象成对象的概念,然后赋予该对象一些属性和方法,之后让这些对象通过自己的方法,去达成最终的目的。
使用面向对象思想进行程序开发,主要的目的就是降低系统的耦合性,设计出易维护、易复用、易拓展的程序。
由于下面会出现面向对象的三个特性–封装、继承、多态,这里也简单介绍一下:
封装:也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
继承:指的是一种能力,一个新的类可以通过继承使用另一个类的所有能力,并在无需重新编写原类的情况下对原类的功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。
多态:指的是同一个方法调用,由于对象不同可能会有不同的行为。
用 go 实现 OOP(分别实现OOP的三个特性)
封装
封装是 go 语言原生就支持的特性,在 go 中,定义一个变量,该变量以大写字母开头,即为导出变量,可以在其他的包中通过包名访问。若是以小写字母开头,则为非导出变量,只能在所在包范围访问。
该规则同样适用于结构体的字段,在定义结构体字段时,字段名的大小写同样表示该字段是否导出,可以通过该规则来实现封装特性,即大写开头的字段为 Public 属性,小写开头的字段为 Private 属性。
1 | type Student struct{ |
继承
提升字段
在结构体中属于匿名结构体的字段称为提升字段,因为它们可以被访问,就好像它们属于拥有匿名结构体字段的结构一样。
如:
1 | type People struct{ |
在这个例子中,People 字段为 Student 结构的匿名字段,Name 和 Age 为 Student 结构的提升字段,Student 的实例可以通过 Name 直接访问 People 字段的 Name 字段。如:
1 | s := Student{} |
实现继承
通过提升字段就可以在 go 中实现继承这个特性,在子类中包含一个匿名的父类字段,此时可以通过子类直接访问父类的属性、调用父类的方法。
上文的例子其实就是一个继承,Student 为子类,People 为父类。在上文的基础上,为 People 结构增加一个 Eat() 方法,Student 结构也可以直接调用该方法。
1 | func (p People)Eat(){ |
同时,Student 结构也可以重写 Eat 方法:
1 | func (s Student)Eat(){ |
多态
go 中的多态可以通过接口(interface)来实现。对于一个接口的实现来说,看成实现本身的类型的话,它能够访问实现类中的属性和方法,看成是对应的接口类型的话,那就只能访问接口的方法。
1 | type Cleaner interface{ |
在 go 中实现多态,要求对外提供的都为接口类型,各个子类的工厂返回的也是接口类型,这样通过工厂返回的对象就只能访问接口定义的方法。
1 | type Inf interface { |
总结
本篇文章我们探讨了如何在 Go 语言中实现面向对象编程,详细介绍了 Go 语言中的结构体、方法和接口,通过实例代码展示了如何使用这些特性来模拟面向对象编程的核心理念,包括封装、继承和多态。
虽然 Go 语言并未直接提供传统面向对象编程中的类和继承机制,但其独特的方式却能有效地实现面向对象的思想。这种方式既保留了面向对象编程的优点,又避免了其复杂性,使我们能够更加专注于解决问题,而不是管理复杂的类结构和继承层次。