‹  返回课程

当“私有的胸”遇上“同班同学的手”

课文
阅读量:390
技术范畴
一则笑话帮你了解什么是类,什么是对象;以及为什么说在C++、C#、Java等语言中,访问权限控制是“面向类型”而不是“面向对象”?
课前导言
提示,这是一则严肃的,有关“面向对象”编程的笑话。
当“私有的胸”遇上“同班同学的手”
一个男人和一个女人在计算机编程课上相遇了……

 

类/class、类的成员访问范围、私有的/private、面向对象……

 

A man and woman are in a computer programming lecture. The man touches the woman’s breasts.

“Hey!” she says. “Those are private!”

The man says, “But we’re in the same class!”

硬译:

一个男人和一个女人在一起听一堂计算机编程课。这个男人伸手摸了女人的胸。

“喂!”她说,“它们是私有的!”

男人回答:“可是我们在同一个班级(class)里啊!”

非要把笑话当真的话,那么这两个人在听的课,应该是C++一类的“面向对象”的编程语言。“面向对象”是一种编程思想、一种程序的组织方式。不同的语言有不同的“面向对象”的实现方法。不同实现方法之间差异有时候是巨大的;但由于以 C++为始作俑者(此词在此处使用,需要稍为弱化其原有的贬义)的一系列以“面对向象”著称的编程语言——典型的如:C++、Java、C#——的影响,使得许许多多程序员以为,面向对象就是这类语言所展现的那一套。

C++、Java、C#三大语言声称的“面向对象”的语法设置中,最“有趣”的一点是,其实它们在语法上更多的是:“面向类型”,而不是“面向对象”。

什么叫对象,对象通常是“活生生”的,具体的一个东西(Obeject)。比如笑话中的一个男人,一个女人,就是两个对象,为方便表达,我们给他们各一个名字,男人叫Tom,女人叫Rose。什么叫类型?不管是Tom还是Rose,他们都是“人类”。人类就是一种类型。类型在有些编程语言里,叫“Type”,但“不巧”的是在这三个非常流行的语言里,它们都使用了笑话中的“class”,而这个词,我们在初中时就知道,它还有“班级”的意思。

作为一个“活生生”的实体,对象通常会拥有一些“属性”和“方法”,也称为“数据”和“行为”。以笑话为例,Rose的“胸”就是她的数据之一,而流氓Tom的“摸”,就是他的一种行为

面向对象听起高大上,但其实它的很多思路源于生活。在现实世界里,只要不是流氓,大多数对象都会本能地想保护自己的数据,不要轻易被别的对象的行为随便碰触。碰触这个词太那个,所以得改成“访问”。让我们再读一遍:

“大多数对象都会本能地想保护自己的数据,不要轻易被别的对象的行为随便访问。”

这中间包含的思想,就是面向对象的“访问控制”。其基本实现思路是,设计者可以归定某些数据是私有的(请在笑话原文中找到“private”),于是它们只能归对象自己访问。

如果依据这个朴素的思想,那么Tom的流氓行为显然不会得逞。但是在C++、C#、Java等极度流行的编程语言中,这个朴素的思想没有得到完全的贯彻。在这些语言里,访问控制面向“类型/class”设置,而不是基于“对象/object”。

构成这个笑话的笑点之一,是英语中的“类型/class”正是也有“班级”之意。所以Tom说其实是:

“我的行为和你的数据在同一个类的定义里,所以依据台上老师所讲,我的行为可以直接访问你的数据。”

如果“class”只有类型的之意没有班级之意,就像翻译成汉事一样,整个笑话就失去了它无厘头的一面。不好像了。但是,在前述的编程语言里,这种看似诡异的现象可完全可以存在。

假设程序的设计者,确实将Tom和Rose都归为同一种类型,比如“人类”。那么人类就拥有“手”和“胸”等属性数据,以及吃喝拉撒等行为方法,当然,我们现在只关心“摸”这个方法。用于示意的伪代码如下:

class 人类
{
    
 公开的方法: 摸(被摸对象);
         
 私有的属性: 左胸,右胸;
 私有的属性: 左手,右手;   
    
};

把重点放在人类的“摸”这个行为的实现。既然是一种行为,通常就有主语和宾语,对应到本例,就是“当前对象”和“被摸对象”之分。完整讲就是 前者的手,去访问后者的胸。如果用 . 来表示 “的”,那么就有如下实现示意:

人类的摸的方法的实现 (被摸对象)
{
     当前对象.手 访问 被摸对象.胸;
}

希望大家应该基本理解了,因为这样一本正经地讲一个流氓例子,实在诡异啊。说一下重点:如果被摸对象是小狗。那么以上代码就不合法。因为狗是狗类,人是人类,二者类型不同,跨类的行为实在令人发指……所以被C++、C#、Java三大“流氓”一致禁止——但如果被摸对象是类型是人类,由于操作代码正好就写在同样的人类的“摸”的方法内部,所以Tom摸Rose……

合法!

课后导言
确实非常严肃,现在你对“面向对象”,特别是C++语言的“面向对象”是否有了新的理解?