面向对象的class和type

面向对象的内涵绝非仅仅只是一个。不同语言,其代表的内涵有所不同,实现的方式也会有所不同。

面向对象的流派

面向对象至少有两种不同的含义,但大多数人只知道其中一种,由此产生了种种偏见。

Simula派系

C++语言设计者本贾尼·斯特劳斯特卢普(Bjarne Stroustrup)在其著作《C++语言的设计和演化》中写道:

是一种创建用户自定义类型的功能。

除此之外,在1991年举办的第一届欧洲软件节上,他在”What is Object-Oriented Programming”(什么是面向对象程序设计)这篇公开的论文中指出:

“Simula的继承机制是解决问题的关键”“面向对象程序设计使用了用户定义类型和继承的程序设计”

Smalltalk派系

“面向对象”一词的发明者艾伦·凯(Alan kay),Smalltalk语言设计者,却持有不同的意见。他解释说:

“我并不是反对类,但是我还没有见过包含类但不让我感到痛苦的系统”

“我并不喜欢Simula里的继承做法”

“通过不同状态的对象互相传送消息来通信的程序设计就是面向对象。”

我们可以看出他对类和继承持否定立场。

什么是类

C++中,类被定义为“用户可自定义的类型”。C++是静态类型语言,而在Python和Ruby这些动态类型语言中,类型一词指的内容和在C++语言中是不一样的。

但是,类真的有必要吗?对于大部分语言的程序设计中,类不是必需的,Java语言是一个例外。Java语言“把类定义为部件,将其组装起来即是程序设计”。因此,用Java语言编写程序时,类是必要的。

2008年诞生的Go语言,居然不支持通常我们所熟知的。Go语言抛弃了太多现代语言的特性,产生了不少争议,人们对其褒贬不一。我个人还是很欣赏这门语言的勇气,但也觉得Go简化得有一些过分了,不支持重载也不支持泛型,实际写代码会很难受的。所以,Julia才是一门恰到好处的语言。

此对象非彼对象

对象实际上是对现实世界的模型

怎么把现实世界的模型放到计算机上,这就是发明对象的初衷,在这之上的哲学扯谈,完全是没必要的。

我们理解世界,将生活中遇到的事物总结为“物”的概念,诸如桌子、椅子、公式、三角形等等。我们的思考、语言以及行动就是建立在指示、说明和操作这些所谓的“物”的基础上。

因此,要把现实世界中的“物”的模型在计算机中建立起来。“物”就是object(对象),模型就是model(模型)。经过一番探讨,面向对象这个概念登场了。

假如我们把面向对象理解对这个世界进行归纳和建立模型,那么语言不同,实现的方式也就是不同。Java和C++语言选取了类,非常有名,以至于大部分人以为这就是世界的全部。不得不说,这是赤裸裸的偏见。

请记住,类的存在只不过是人们觉得有了它编写程序会更加方便,进而约定的一种事项。它并不是什么物理法则或者宇宙真理,仅仅就是一种约定。

模块、包

模块是一种将相关联的函数集中到一起的功能。在1978年的Modula-2语言中有了模块的概念。Python语言和Ruby延续了这个概念,继续称为模块,Java语言和Perl语言则把它称为包。

模块是一种归集的方法。那就可以用它来归集变量和函数,进而设计现实世界对象的模型。这个概念大家还是比较熟悉的。

把函数也放入散列

JavaScript用来另一种归集的方法,把函数也放入散列。换句话说,把函数也视为一等公民(first-class citizen)。

大部分编程语言都可以把字符串赋值给变量,用作函数的参数传递或作为函数的返回值返回。但是,在一些语言中,函数没有这种待遇,被歧视了。

并不是所有语言都可以把字符串赋给变量,比如Fortran 66。

在JavaScript语言中,函数也是一等公民。可以赋值给变量,可以作为函数返回值。

闭包

闭包(closure)这个概念,很多人都说不清楚究竟什么是闭包。它是创建具有对象性质的事物的一种技术。

如果存在包含R的具有性质P的关系S,并且S是所有包含S且具有性质P的关系的子集。那么S叫做R的关于性质P的闭包。——《离散数学及其应用》

在一本关于ML语言的教材Functional programming using standard ML中对为什么叫做闭包有这样的解释:

一个包含了自由变量的开放表达式,它和该自由变量的约束环境组合在一起后,实现了一种封闭的状态。

很多语言都支持带有某种状态的函数,只要它在函数中可以定义函数,允许嵌套的静态作用域,并且可以把函数作为返回值传递给变量,那么它只要通过函数嵌套就可以实现带有某种状态的函数。

大部分函数式语言和JavaScript以及Python,包括Julia都支持闭包。Ruby和Perl经过一些处理也可以符合这种要求。

类,这个大家最熟悉的概念放到最后。

C++和Java语言的类具有以下几个作用:

整合体的生成器(类是模具)

可以操作的功能说明(Java的接口,动态语言不太重视这种作用)

代码复用的单位

现在C++和Java语言使用的被追加了很多意思,变得无比的复杂,但最初都是分类的意思。什么类的继承、实例的模型,这都是后来的概念。

Julia的type

类是类型。这是C++语言中极为重要的一种思想。既然C++中类的意思就是用户定义的类型,那为什么不把它叫做呢?我之所以选择使用,是因为实在不喜欢不断地创造新词,才选用Simula语言中class这个谁都不至于困惑的词。

——Bjarne Stroustrup《C++语言的设计与演化》

能让用户定义新的、操作起来如同和这样内置的类型,这是C++引入类的目的。大概也是这样的原因,C++支持操作符重载。可见,Julia的,其实和类没什么太大不同,只不过Julia学习Go,没有搞得太复杂。

小结

什么对象,还是赶紧找个女朋友吧。

有了?那,再一个……

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180512G1V6EE00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

同媒体快讯

扫码关注云+社区

领取腾讯云代金券