Go是面向对象吗?

关于Go是否是面向对象编程语言,这个问题在GO的社区也有很多讨论,众说纷纭,而GO的官方给出的答案是:YES OR NO,是也不是。针对这个答案,我们可以从面向对象的一些特性来进行剖析一下。

是否面型对象

Go不是面向对象

1、Go本身是一门面向过程、并发编程的语言

2、Go 在语法上并不是典型的面向对象语言,它没有类(class)的概念,也没有继承(inheritance)和多态(polymorphism)的特性

Go是面向对象

1、虽然Go语言在语法上不是面向对象,但是提供一些面向对象编程的特性,这一点从java转到go的同学是深有体会,在刚进入go的编程时总会延用以前java的设计思路,感觉这就是一门面向对象的编程语言

Go面向对象特性

从上面的结论上我们也知道了,Go语言从设计和语法上本身不是一门面向对象的语言,但是它提供了一些面向对象的特性,使得开发人员可以写出类似面向对象设计的代码。面向对象的三大特性:封装、集成和多态,那么我们就从这三个特性看看Go是如何实现的

封装

封装是将数据(属性)和操作数据的方法(行为)捆绑在一起,形成一个独立的单元。通过封装,对象的内部实现细节被隐藏,只有对象的接口是可见的,外部代码无法直接访问对象的内部数据,在面向对象语言中,封装是类class提供的特性。

Go语言没有class的概念,但是提供了结构体(struct)的定义,我们可以在结构体里定义属性,然后通过创建结构体示例来访问属性,但是结构体内部无法封装行为,对结构体的行为是在结构体外部定义的。

package extension

import (
	"fmt"
	"testing"
)

//定义结构体
type Person struct {
	Name string
	Age int32
	Address string
}

//定义行为
func (p *Person) speak() {
	println(p.Name)
}

func TestPerson(t *testing.T) {
	//创建实例
	var person = new(Person)
	
	//设置属性
	person.Name = "张三"
	person.Age = 20
	person.Address = "武汉"
	
	//调用行为
	person.speak()
}

继承

继承允许一个类(子类/派生类)继承另一个类(父类/基类)的属性和方法。子类可以继承父类的特性,可以重用父类的代码,并且可以在不修改父类代码的情况下进行扩展。

Go的语法里并没有继承的概念,但是可以通过组合的使用来达到类似继承的效果,但是这种做法本身和继承又有一些区别。

继承父类方法:

package extension

import (
	"fmt"
	"testing"
)


type Pet struct {
}

func (p *Pet) Speak() {
	fmt.Print("pig")
}


type Dog struct {
	Pet //继承Pet
}

func TestDog(t *testing.T) {
	dog := new(Dog)
	dog.Speak() //调用Pet方法
}

//输出pig

重写父类方法:

package extension

import (
	"fmt"
	"testing"
)

type Pet struct {
}

func (p *Pet) Speak() {
	fmt.Print("pig!")
}

func (p *Pet) SpeakTo(host string) {
	p.Speak()
	fmt.Println(" ", host)
}

type Dog struct {
	Pet //继承Pet
}

func (d *Dog) Speak() {
	fmt.Print("dog!")
}

func TestDog(t *testing.T) {
	dog := new(Dog)
	dog.Speak() //调用Pet方法
}

//输出dog

父类调用子类方法:这里可以看出差别,并不是真的继承

package extension

import (
	"fmt"
	"testing"
)


type Pet struct {
}

func (p *Pet) Speak() {
	fmt.Print("pig!")
}

func (p *Pet) SpeakTo(host string) {
	p.Speak()
	fmt.Println(" ", host)
}

type Dog struct {
	Pet //继承Pet
}

func (d *Dog) Speak() {
	fmt.Print("dog!")
}

func TestDog(t *testing.T) {
	dog := new(Dog)
	dog.SpeakTo("host") //调用父类方法
}

//输出pig而不是dog

多态

多态允许不同类的对象对同一个消息(方法调用)作出响应,这个消息可以是类的方法。在多态中,同样的方法可以有不同的实现,具体执行哪个实现是在运行时决定的。多态提高了代码的灵活性和可扩展性。

在面向对象语言中,多态和继承一般是紧密相连的,但是在Go中没有继承的概念,多态的特性是通过接口(interface)来实现。

package interface_test

import "testing"


type Pet struct {
}

func (p *Pet) eat() {
	fmt.Print("pig!")
}

type Dog struct {
}

func (d *Dog) eat() {
	fmt.Print("dog!")
}

type Animal interface {
	eat()
}

func TestAnimal(t *testing.T) {
	var a Animal //定义一个Animal类型变量
	a = new(Pet)
	a.eat()
	//输出pig!

	a = new(Dog)
	a.eat()
	//输出dog!
}

上面这个代码是不是完全就是多态的行为了。

到这里大家对Go是否是一门面向对象的语言是不是已经有了答案,就单从语言的语法和设计上来看Go确实不是一门面向对象语言,但是它里面提供了一些面向对象的特性,我们可以采用不同的方式来实现面向对象的一些设计,所以这里说的是提供了面向对象的特性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值