大家在早期学习 Go 时,一旦跨过语法的阶段后。马上就会进入到一个新的纠结点,Go 不支持面向对象吗?

图片

这门编程语言里没有类(class)、继承(extends),没法一把搜了,面试问啥面向对象(OOP)?

今天煎鱼就带大家一起来了解这之中的思考,Go 真的不支持吗?

类和继承

类是什么

类(class)在面向对象编程中是一种面向对象计算机编程语言的构造,是创建对象的蓝图,描述了所创建的对象共同的特性和方法(via @维基百科)。

例子如下:

class SimpleClass
{// 声明属性public $var = '脑子进煎鱼了';// 声明方法public function displayVar() {echo $this->var;}
}

每个类的定义都以关键字 class 开头,后面跟着类名,后面跟着一对花括号,里面包含有类的属性与方法的定义。

继承是什么

继承是面向对象软件技术当中的一个概念,如果一个类别 B “继承自”另一个类别 A,就把这个 B 称为 “A的子类”,而把 A 称为 “B的父类别” 也可以称 “A 是 B 的超类”(via @维基百科)。

例子如下:

// 父类
class Foo
{public function printItem($string){echo '煎鱼1: ' . $string . PHP_EOL;}public function printPHP(){echo 'PHP is great.' . PHP_EOL;}
}// 子类
class Bar extends Foo
{public function printItem($string){echo '煎鱼2: ' . $string . PHP_EOL;}
}

继承有如下两个特性:

  • 子类具有父类别的各种属性和方法,不需要再次编写相同的代码。

  • 子类别继承父类时,可以重新定义某些属性,并重写某些方法,使其获得与父类别不同的功能。

结构和组合

在 Go 里就比较 ”特别“ 了,因为没有传统的类,也没有继承。

取而代之的是结构和组合的方式。这也是业内对 Go 是否 OOP 争议最大的地方。

结构体

我们可以在 Go 中通过结构体的方式来组织代码,达到类似类的方式。

例子如下:

package mainimport "fmt"type person struct {name stringage  int
}func(p *person) hello(){}func newPerson(name string) *person {p := person{name: name}p.age = 42return &p
}func main() {fmt.Println(person{"煎鱼1", 22})fmt.Println(person{name: "煎鱼2", age: 33})...
}

在上述代码中,我们可以定义结构体内的属性,也可以针对结构体这些类型定义只属于他们的方法。

在声明实例上,可以配合 newXXX 的初始化方法来生成,这是 Go 里约定俗成的方式。

组合

类的声明采取结构体的方式取代后,也可以配套使用 ”组合“ 来达到类似继承的效果。

例子如下:

type man struct {name string
}func (m *man) hello1() {}type person struct {manname string
}func (p *person) hello2() {}func newPerson(name string) *person {p := person{name: name}return &p
}func main() {p := newPerson("脑子进煎鱼了")p.hello1()
}

在上述代码中,我们分别定义了 man 和 person 两个结构体,并将 man 嵌入到 person 中,形成组合。

你可以在 main 方法中能够看到,person 实例是可以使用和调用 man 实例的一些公开属性和方法的。

在简单的使用效果上会与继承有些接近。

Go 是面向对象的语言吗

“Go 语言是否一门面向对象的语言?”,这是一个日经话题。官方 FAQ 给出的答复是:

图片

是的,也不是。原因是:

  • Go 有类型和方法,并且允许面向对象的编程风格,但没有类型层次。

  • Go 中的 "接口 "概念提供了一种不同的方法,我们认为这种方法易于使用,而且在某些方面更加通用。还有一些方法可以将类型嵌入到其他类型中,以提供类似的东西,但不等同于子类。

  • Go 中的方法比 C++ 或 Java 中的方法更通用:它们可以为任何类型的数据定义,甚至是内置类型,如普通的、"未装箱的 "整数。它们并不局限于结构(类)。

  • Go 由于缺乏类型层次,Go 中的 "对象 "比 C++ 或 Java 等语言更轻巧。

为什么不支持类和继承

有的人认为类和继承是面向对象的必要特性,必须要有,才能是面向对象的语言,但其实也并非如此。

面向对象(OOP)有不同的含义和解读,许多概念也可以通过结构体、组合和接口等方式进行表达,说是不支持传统的 OOP。

其实真相是 Go 是选择了另外一条路,也就是 ”组合优于继承“。我们所提到的类和继承并不是定义 OOP 的一种准则,只是协助完成 OOP 的方法之一。

不要本末倒置了,不让工具来定义 OOP 的理念。

总结

在今天这篇文章中,我们介绍了常说的类和继承的业内定义和使用案例。同时面向 Go 读者群里的疑惑,进行了解答。

实质上,Go 是 OOP,也不是 OOP。类和继承只是实现 OOP 的一种方式,但并不是没有这两者,他就不是 OOP 了。

不支持的原因也很明确,Go 在设计上,选择了组合优于继承的编程设计模式,它不是传统那种面向类型的范式。

你觉得呢,欢迎大家在评论区留言和交流:)

看完煎鱼大佬的分析是不是觉得好像懂了,又好像没完全懂。其实是不是面向对象不用纠结,理解Go选择组合而不是继承,设计代码的时候记着不要想着哪个抽象方法留给子类实现,而是直接把具体类型用组合进来去调用,就基本上不会踩坑。

关注煎鱼,获取最新的一手知识 

Go 到底算不算一门面向对象的编程语言相关推荐

  1. python是一门面向对象的编程语言_python面向对象

    第六章 对象(Object) 什么是对象? - 对象是内存中专门用来存储数据的一块区域. - 对象中可以存放各种数据(比如:数字.布尔值.代码) - 对象由三部分组成: 1.对象的标识(id) 2.对 ...

  2. 深度linux_国产系统?基于Linux研发的深度Deepin系统,到底算不算真国产

    阅读本文前,请您先点击上面的蓝色字体"晓艳观世界",再点击"关注",这样您就可以免费收到最新内容了.每天都有分享,完全是免费订阅,请放心关注. 近年来,国内科技 ...

  3. 华为手机怎样才算激活了_外观专利到底怎样才算侵权呢?

    外观专利到底怎样才算侵权呢? 外观设计的侵权判定: 一.确定外观设计专利权的保护范围 根据专利法第五十九条第二款之规定,其保护范围,以表示在外观设计专利权人在申请外观设计专利时向专利局提交的图片或者照 ...

  4. 超级计算机能算数学题吗,圆周率到底能不能算尽?人类拿超级计算机算了一下,结果不敢相信...

    校长科普 2018-12-11 01:16 圆周率到底能不能算尽?人类拿超级计算机算了一下,结果不敢相信 说到圆周率,读过书的小伙伴应该都很清楚吧,在数学课上最有意思的就是算圆周率了.记得校长初中的时 ...

  5. 超级计算机也无法算尽圆周率,圆周率到底能不能算尽?

    说到圆周率,读过书的小伙伴应该都很清楚吧,在数学课上最有意思的就是算圆周率了.记得校长初中的时候老师就组织我们计算圆周率以此来考核我们的计算能力,记得校长那个时候算到了圆周率后50位的数字,现在想想还 ...

  6. 冯东阳:解读纯文本链接到底算不算外链

    很多做SEO的可能都比较迷惑,自己发的外链是纯文本链接,这算是外链吗?不只一个人问过老冯(冯东阳)这个问题,刚好,今天下午在群里看到一个人也问纯文本链接算不算外链的事,我就发表下我的意见吧! 纯文本也 ...

  7. 圆周率用计算机能算出来不,圆周率到底能不能算尽?人类拿超级计算机算了,结果不敢相信!...

    提到圆周率,我们大部分人应该都不会觉得陌生,就这样东西来说,往往我们的首次接触都是在初中的时候.那时候的很多数学老师也会用让学生计算圆周率来评估他们的计算能力.事实上,圆周率是可以一直循环下去的,对此 ...

  8. MD5 到底算不算一种加密算法?

    一旦提到加密算法,经常有人会有这样的疑问:MD5 到底算不算一种加密算法呢? 在回答这个问题之前,我们需要先弄清楚两点: 什么是加密算法? 什么是 MD5? 1.什么是加密算法? 数据加密的基本过程就 ...

  9. 【科普】超算到底是咋算的?

        最近一段时间,有关超算的话题成为热门,一时间大家都开始讨论超算,各种浮于表面的吹牛,逼格负无穷的装逼.然而,冬瓜哥发现在所有这些讨论中,从没有在任何时间任何地点发现任何人问出就连小学生都经常问 ...

最新文章

  1. LED的电流与光强之间的关系
  2. asp.net 漂亮搜索框_推荐4款影视搜索工具,十一假期让你看剧看到爽
  3. Android 部分机型GridView四周默认间距
  4. 向数据库中导入AWR数据
  5. java8日期转时间戳_Java 8日期和时间
  6. 一起学习Windows Phone7开发(十八. Windows Phone7 Toolkit)
  7. MQTT 消息通信工具使用
  8. Win下的驱动备份与还原
  9. linux 断开远程vnc,Linux停VNC远程控制的使用方法
  10. 全球计算机大学排名!软科世界一流学科排名
  11. 软件测试度量的关键指标,软件测试度量指标简介
  12. NIVIDIA Tegra K1 QWT安装使用问题和解决办法
  13. 淘宝旺旺号转userid 或 uid 接口与方法
  14. UE4(虚幻4)做一个双开平移自动门+双开旋转门+使用相对坐标
  15. 28超信界面的布局设计
  16. 销售开发新客户的方法 如何开拓新客户
  17. Spring AOP(切面面向接口)
  18. 【Python】实现给小仙女定时推送消息
  19. 简单操作破解PDF加密文件
  20. 国外服装设计师的网站(全)

热门文章

  1. SpringBoot 数据篇之使用JDBC
  2. ArcGIS Python编程案例-电子资料链接
  3. 【转】file_get_contents(php://input)的使用方法
  4. py3下怎么用StringIO
  5. LBS移动网络基站定位
  6. IOS 传值方法总结
  7. SOAP的Could not connect to host in...报错解决方案
  8. SQL Server 2005数据库快照
  9. 学android开发,入门语言JAVA知识点
  10. Nginx + Tomcat Windows下的负载均衡配置