天天看点

Go 去找个对象吧

Go 去找个对象吧

我的读者中应该大部分都是 <code>Java</code> 从业者,不知道写 <code>Java</code> 这些年是否真的有找到对象?

没找到也没关系,总不能在一棵树上吊死,我们也可以来 <code>Go</code> 这边看看,说不定会有新发现。

开个玩笑,本文会以一个 <code>Javaer</code> 的角度来聊聊 <code>Go</code> 语言中的面向对象。

面向对象这一词来源于<code>Object Oriented Programming</code>,也就是大家常说的 <code>OOP</code>。

对于 <code>Go</code> 是否为面向对象的编程语言,这点也是讨论已久;不过我们可以先看看官方的说法:

Go 去找个对象吧

其他的我们暂且不看,<code>Yes and No.</code> 这个回答就比较微妙了,为了这篇文章还能写下去我们先认为 <code>Go</code> 是面向对象的。

面向对象有着三个重要特征:

封装

继承

多态

<code>Go</code> 并没有 <code>Class</code> 的概念,却可以使用 <code>struct</code> 来达到类似的效果,比如我们可以对汽车声明如下:

与 <code>Java</code> 不同的是,<code>struct</code> 中只存储数据,不能定义行为,也就是方法。

当然也能为 <code>Car</code> 定义方法,只是写法略有不同:

在方法名称前加上 <code>(car *Car)</code> 便能将该方法指定给 <code>Car</code> ,其中的 <code>car</code> 参数可以理解为 <code>Java</code> 中的 <code>this</code> 以及 <code>Python</code> 中的 <code>self</code>,就语义来说我觉得 <code>go</code> 更加简单一些。

毕竟我见过不少刚学习 <code>Java</code> 的萌新非常不理解 <code>this</code> 的含义与用法。

既然谈到结构体了那就不得不聊聊 <code>Go</code> 支持的匿名结构体(虽然和面向对象没有太大关系)

<code>Go</code> 允许我们在方法内部创建一个匿名的结构体,后续还能直接使用该结构体来获取数据。

这点在我们调用外部接口解析响应数据时非常有用,创建一个临时的结构体也不用额为维护;同时还能用面向对象的方式获取数据。

相比于将数据存放在 <code>map</code> 中用字段名获取要优雅许多。

<code>Go</code> 语言中并没有 <code>Java</code>、<code>C++</code> 这样的继承概念,类之间的关系更加扁平简洁。

各位 <code>Javaer</code> 应该都看过这类图:

Go 去找个对象吧

相信大部分新手看到这图时就已经懵逼,更别说研究各个类之间的关系了。

不过这样好处也明显:如果我们抽象合理,整个系统结构会很好维护和扩展;但前提是我们能抽象合理。

在 <code>Go</code> 语言中更推荐使用组合的方式来复用数据:

这样我们便可以将公共部分的数据组合到新的 <code>struct</code> 中,并能够直接使用。

面向接口编程的好处这里就不在赘述了,我们来看看 Go 是如何实现的:

首先定义了一个接口 <code>RunService</code>;<code>ElectricCar</code> 与 <code>PetrolCar</code> 都实现了该接口。

可以看到 <code>Go</code> 实现一个接口的方式并不是 <code>implement</code>,而是用结构体声明一个相同签名的方法。

这种实现模式被称为”鸭子类型“,<code>Python</code> 中的接口也是类似的<code>鸭子类型</code>。

Go 去找个对象吧

详细介绍可以参考这篇:Python 中的面向接口编程

接口当然也是可以扩展的,类似于 <code>struct</code> 中的嵌套:

Go 去找个对象吧

得益于 <code>Go</code> 的强类型,刚才的 <code>struct</code> 也得实现 <code>DiService</code> 这个接口才能编译通过。

到这里应该是能理解官方所说的 <code>Yes and No.</code> 的含义了;<code>Go</code> 对面向对象的语法不像 <code>Java</code> 那么严苛,甚至整个语言中都找不到 <code>object(对象)</code> 这个关键词;但是利用 <code>Go</code> 里的其他特性也是能实现 <code>OOP</code> 的。

是否为面向对象我觉得并不重要,主要目的是我们能写出易扩展好维护的代码。

例如官方标准库中就有许多利用接口编程的例子:

Go 去找个对象吧

由于公司技术栈现在主要由 <code>Go</code> 为主,后续也会继续更新 <code>Go</code> 相关的实战经验;如果你也对学习 <code>Go</code> 感兴趣那不妨点个关注吧。

作者:

crossoverJie

出处:

https://crossoverjie.top

Go 去找个对象吧

欢迎关注博主公众号与我交流。

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出,

如有问题, 可邮件(crossoverJie#gmail.com)咨询。