「我的读者应该大多数都是java或者php的从业者,不知道写java写php这么多年是否找到对象,没找到也没关系,总不能在一棵树上吊死,我们也可以来 Go 这边看看,说不定会有新发现」。
我记得才学习golang的时候,都说go语言是不支持面向对象的,但是golang又可以支持封装、继承、多态这些特性,所以golang到底值不支持面向对象呢?经过多方资料的查阅,得出如下结论
接下来咱们就从封装,继承,多态三个方面来给大家介绍一下golang的面向对象。
一般语言中的面向对象封装都类似这样(伪代码)
class Person{
name
age
function eat(){
return "eat"
}
}
都是用一个「class关键字」来定义一个类,并且可以自定义他的一些属性和方法,这种行为咱们也叫做「封装」
go语言中是「不支持class关键字」的,但是可以用「struct」达到类似的效果
type Person struct{
name string
age int
}
但是和其他语言不同,struct关键字只能定义属性,但是不支持行为,也就是不能定义方法。golang既然支持面向对象那么肯定是能支持方法的,只不过是写法稍微有些不同。golang是通过下面的方式进行方法绑定的
func (this *Person) GetName() {
fmt.Printf(this.Name)
}
func main(){
person := Person{
Name: "xiaofan",
Age: 18,
}
person.GetName() //执行Person绑定的方法GetName
return
}
其实就是一个简单的golang函数,在前面加上(this *Person)就可以实现方法的绑定,其实很多同学在这里对this不是很理解,在这里作出如下声明
下面是一些在实际中封装的时候需要注意的地方,大家可以看看
我们先来看看其他语言一般是怎么继承的(伪代码)
class Person {
name string
function eat(){
print("eat 方法")
}
}
class Student extens Person{ //student类继承Person类之后就可以用Person类的属性和方法了
}
但是在go里面继承的方法比较特殊,如下
type Person struct {
Name string
Age int
}
func (this *Person) GetName() {
fmt.Printf(this.Name)
}
type Student struct{
Person //这样Student类就可以继承Person类了
Score int //student类自己的属性
}
func main(){
stu := Student{}
stu.Name = "小饭" //继承父类的属性
stu.GetName() //继承父类的方法
return
}
多态是同一个行为具有多个不同表现形式或形态的能力。
golang中的多态是通过interface类型实现的
type Person interface { //接口Person规定了方法GetName
GetName()
}
type Student struct {
Name string
Age int
}
func (this *Student) GetName() {
fmt.Println(this.Name)
}
type Teacher struct {
Name string
Age int
}
func (this *Teacher) GetName() {
fmt.Println(this.Name)
}
但是我们是否发现了一个问题,Student和Teacher是按照Person的标准去实现的,但是从上述代码看的话,他们互相之间好像没什么联系,所以把类和接口关联的话还得看下面的代码
func main() {
var stu Person //定义变量为接口类型
stu = &Student{
Name: "小饭",
Age: 123,
}
stu.GetName()
var teacher Person //定义变量为接口类型
teacher = &Teacher{
Name: "老师",
Age: 23,
}
teacher.GetName()
}
当然上述方法我们可以稍微改造一下
func GetName(p Person) {
p.GetName()
}
func main() {
stu := Student{
Name: "小饭",
Age: 123,
}
GetName(&stu)
}
这种实现模式被称为”鸭子类型“,Python 中的接口也是类似的鸭子类型。
到这里应该是能理解官方所说的 Yes and No. 的含义了;Go 对面向对象的语法不像其他语言 那么严苛,甚至整个语言中都找不到 object(对象) 这个关键词;但是利用 Go 里的其他特性也是能实现 OOP 的。