1. 引言
提起面向对象,每个程序设计者总会说出一堆自己的理解,有独特的、有偏废的,不尽而然。但是无论所云,几个基本的概念总会得到大家的首肯,它们是:类、对象、继承、封装和多态。很对,差不多就是这些概念构成了面向对象设计开发技术的基本逻辑,成为数以千万计程序设计者不懈理解和实践的标语。而实际上,理解面向对象一个重要的方法就是以实际的生活来类比对象世界,对象世界的逻辑和我们生活的逻辑形成对比的时候,我们的理解将会更有亲切感,深入程度自然也就不同以往,因为谁能对生活没有理解呢?
本文,就从对象这一最基本元素开始,进行一次深度的对象旅行,把.NET面向对象世界中的主角来次遍历式曝光。 把对象的世界和人类的世界进行一些深度类比,以人类的角度来戏说对象,同时也以对象的逻辑来反思人类。究竟这种品查,会有什么样的洞悉,看我且来演义。
2 出生
对象就像个体的人,从生而来,入世而归。
我们对对象的戏说就从对象之生开始吧。首先,看看一个对象是如何出生的:
Person aPerson = new Person("Xiao Wang", 27);
那么一个人又是如何出生呢?每个婴儿随着一声啼哭来到这个世界,鼻子是鼻子、嘴巴是嘴巴,呱呱落地,一个可爱的生命来到人间。可见,怀胎十月是人出世之前的成长过程,母亲为孩子提供了一切出世为人的环境,这个过程就是一次实实在在的生物化构造。同样的道理,对象的出生,也是一次完整的构造过程:首先会在内存中分配一定的存储空间;然后初始化其附加成员,就像给人取个标识的姓名一样;最后,再调用构造函数执行初始化,这样一个对象实体就完成了其出生的过程,例如上例中我们为aPerson对象初始化了姓名和年龄。
正如人出生之时,一身赤裸没有任何的附加品,一切的所属品将在生命的旅程中逐渐完善,生不带来就是这个意思。对象的出生也只是完成了对必要字段的初始化操作,其他的数据要等后面的操作来完成。例如对属性赋值,通过方法获取必要的信息等待。
3 旅程
新生的孩子一经出世,就来到人间,加入了人类这个大家庭,社会这个大环境。从而经历一次在人类伦理与社会规则的双重标准中生活,这就是人的旅程。同理,对象也一样。
最为个体的人,首先是有类型之分的,农民、工人、学者、官员等等,为的是方便管理,所以形成的社会规则就是农民一般居住在农村,工人一般生活在城市,学者探讨知识,官员管理国家。
对象也是一样,是有类型的,例如整型、字符型等等。当然,分类的标准不同,得到的角度也会不同,但是常见的分类就是值类型和引用类型两种。其依据是对象在运行时在内存中的位置,值类型位于线程的堆栈,而引用类型位于托管堆。正如,农民也可以进城生活,工人也可以隐居于乡村,值类型和引用类型的角色也会发生转变,这个过程在面向对象中称为装箱与拆箱。这点倒是有些变相的贴切,农民进城,工人回乡,不都得把行李装进箱子里折腾嘛。
作为人,我们都是有属性的,例如你的名字、年龄、籍贯等等,用于描述了你的状态信息,同时每个人也有不同的行为来操作自己的属性,实现了与外界进行交互的手段。对象的字段、属性就是我们自己的标签,例如人的姓名、性别、年龄和身份;而方法就是操作这些标签的行为。人的名字来自于父母,是每个人在出生之时构造的,这和对象产生时给字段赋值一样。但是每个人都有随时更名的权力,这种操作自己名称的行为,我们称之为方法。在面向对象中,可以像这样来完成:
aPerson.ChangeName("Apple Boy");
所以,对象的旅行过程,在某种程度上就是以方法与外界进行交互,从而达到改变对象状态信息的过程,这也和人的生存过程是一致的。
人与人的交互是通过语言。既然生则为人,就必然和这个世界的其他人发生交流与切磋,从而才构成一个流动的社会群体,这应该是社会学的基本常识。在对象的世界里,你得绝对相信对象之间也是相互关联的,不同的对象之间发生着不同的交互性操作,那么对象的交互是通过什么方式呢?对象的交互方式被记录在一个称为设计模式的魔法书中,当你不解以什么样的方式建立对象与对象之间的关系时,学习前人的经验是最好的选择,有时候弯路就是这样变成捷径的。
下面,我们简要的分析一下对象到底旅行在什么样的世界里?
对象的载体是CLR,而人的载体是社会。CLR提供了对象赖以生存的规则,称之为语法,例如类型、继承、多态、垃圾回收等等,对象世界建立了真正的法制秩序;而社会提供了人行走江湖的秩序,称之为法律,例如版权、人权、产权,这是我们力图实现的社会秩序。
人类社会就是系统架构,也是分层的。上层建筑代表管理与民主,而人民大众则在底层完成价值的创造。上层建筑靠协约与法律来管理个体的人,在对象世界中,这称之为接口。面向接口的编程就是以接口方式来抽象变化,从而形成体系。而人类不是也以法律手段来维系社会体系的运作和秩序吗,这是它们的神似。
由此可见,对象的旅行就是这样一个过程,在一定的约定与规则下,通过方法进行彼此的交互操作,从而达到改变本身状态的目的。虽然这种概括未免牵强,但是从最简单的方式理解实际情况,也确实如此,这些体会的确可以从人的旅程中得到启示。
4 插曲
接下来,我们以几个最熟悉的概念来进一步阐释对象世界与人类世界的和谐统一。
关于继承。人的社会中,继承一般发生在有血缘关系的族群中。最直接的例子一般是,儿子继承父亲,包括姓氏、基因、财产和一切可以遗留的东西。但并不代表可以继承所有,因为父亲隐私的那一部分属于父亲独有,不可继承。当然,也可能是继承于族群的其他人,视实情而定。而在面向对象中,继承无处不在,子类继承父类,以访问权限来实现不同的控制规则,称为访问级别,主要包括:
访问修饰符
|
访问权限
|
pubic
|
对访问成员没有限制,属于最高级别访问权限
|
protect
|
访问包含类或者从包含类派生的类。
|
internal
|
访问仅限于程序集。
|
protected internal
|
访问仅限于从包含类派生的当前程序集或类型。也就是同一个程序集的对象,或者该类及其子类可以访问。
|
private
|
访问仅限于包含类型。
|
这些规则,以人的视角来理解,我们以公司的体制来举例说明,将公司职权的层级与面向对象的访问权限层级做以类比,应该是这个样子:
· public,具有最高的访问权限,就像是公司的总经理具有最高的决策权与管理权,因此public开发性最大,是的不管是同一个程序集或者不管是否继承,都可以访问;
· protected,类似于公司业务部门经理的职责,具有对本部门的直接管辖权,在面向对象中就体现为子类继承这种纵向关系的访问约定,也就是只要继承了该类,则其对象就有访问父类的权限,而不管这两个具有继承关系的类是否在同一个程序集中;
· internal,具有类比意义的就是internal类似于公司的职能部门的职责,不管是否具有上下级的隶属关系,人力部都能管辖所有其他部门的员工考勤。这是一种横向的职责关系,在面向对象中用来表示同一程序集的访问权限,只要是隶属于同一程序集,则对象即可访问其属性,而不管是否存在隶属关系。
· protected internal,可以看作是protected internal的并集,就像公司中掌管职能部门的副总经理,从横向到纵向都有管理权。
· private,具有最低的访问权限,就像公司的一般员工,管好自己就行了。因此,对应于面向对象的开发性最小。
另外,对象中的继承的目的是提高软件复用,而人类中的继承,不也是现实中的复用吗?
关于多态。人的世界中,我们常常在不同的环境中表现为不同的角色,并且遵守不同的规则。例如在学校我们是学生,回到家里是儿女,而在车上又是乘客,同一个人在不同的情况下,代表了不同的身份,在家里你可以撒娇但是在学校你不可以,在学校你可以打球但在车上你不可以。所以这种身份的不同,带来的是规则的差异。在面向对象中,我们该如何表达这种复杂的人类社会学呢?显然,我们让不同角色的Person继承同一个接口:IPerson。然后将不同的实现仍给不同角色的人自行负责,不同的是PersonAtHome在实现时可能是CanBeSpoil (),而PersonOnBus可能是BuyTicket()。不同的角色实现不同的规则,也就是接口协定。在使用上的规则是这个样子:
IPerson aPerson = new PersonAtHome();
aPerson.DoWork();
另一个角色又是这个样子:
IPerson bPerson = new PersonOnBus();
bPerson.DoWork();
由此带来的好处是显而易见的,我们以IPerson代表了不同角色的人,在不同的情况下实现了不同的操作,而把决定权交到系统自行处理。这就是多态的魅力,其乐无穷中,带来的是面向对象中最为重要的特性体验。记住,很重要的一点是,DoWork在不同的实现类中体现为同一命名,不同的只是实现的内部逻辑。
由此可见,以我们自己的角度来阐释技术问题,有时候会有意想不到的收获,否则你将被淹没在诸如为什么以这种方式来实现复用的叫喊中不能自省。换一个角度,理一种思路,眼界与思路都会更加开阔。
5 消亡
对象和人,有生必然有死。在对象的世界里,它的生命是由GC控制的,而人的世界我们把GC称作为自然规律。不死的人,就像进入死循环的对象,都是违反规则的,终究被Kill的命运。
在这一部分,我们首先观察对象之死,以此反思和体味人类入世的哲学,两相比较,也会给我们更多关于自己的启示。对象的生命周期由GC控制,其规则大概是这样:GC管理所有的托管堆对象,当内存回收执行时,GC检查托管堆中不再被使用的对象,并执行内存回收操作。不被应用程序使用的对象,指的是对象没有任何引用。关于如何回收、回收的时刻,以及遍历可回收对象的算法,是个较为复杂的问题,我们将以专题加以讨论。不过,从这个回收过程中,足以给人类更多的启示来反思,自己生存与世的道理,大自然就是那么看不见的GC,要想努力的活着,就不要使自己变成可回收的垃圾,而是有益与人的人。
5. 结论
程序世界其实和人类世界有很多相似的地方,本文就以这种类比的方式来诠释程序世界的主角如何类似于人类社会的主角,以演化推进的手段来描述面向对象程序世界的主角:对象由生而死的全过程,借以品味一下复杂的人类世界主角。人,也是可以简单的。所以这是一种相互的较量,也是一种相互的借鉴。
本篇纯属戏说,若有雷同,望请笑纳。
分享到:
相关推荐
当Y1,Y2,…..,Yi-1都 能推出ε, (1), 而Yi推不出ε,则FIRST(Y1)--{ε},FIRST(Y2)--{ε},……,FIRST(Yi-1)--{ ε}, FIRST(Yi) 都属于 FIRST(X)。 5. 当4中所有的 Yi都能推出ε,(i=1,2,….n),则 FIRST(X)=FIRST(Y1)...
在编译原理中,求解First集和Follow集是语法分析器设计中的关键步骤,尤其在自顶向下解析策略中尤为重要。First集是指一个非终结符产生的所有串中第一个符号的集合;而Follow集则是指在文法的所有推导过程中,跟随...
根据给定的信息,本文将详细解释如何通过编程方式计算上下文无关文法(Context-Free Grammar, CFG)中的First集和Follow集。First集是对于一个符号(非终结符),能够直接推导出的第一个符号(包括终结符和空串^)的...
在编译原理中,`First`集合和`Follow`集合作为语法分析的重要工具,用于构建预测分析表,进而实现自顶向下的语法分析。这两个概念是编译器设计的基础,帮助我们理解文法的结构并指导词法分析器和解析器的构建。 ...
如果First(B)包含ε且First(C)也包含ε,或者First(B)不包含ε,那么First(A)将包含First(C)的所有元素。 接下来,我们讨论如何求解Follow集合。Follow集合是某个非终结符所能跟随的终结符的集合,它反映了在文法...
### 编译原理:求First集与Follow集 在编译原理中,解析上下文无关文法(Context-Free Grammar, CFG)是理解源代码结构的关键步骤之一。First集与Follow集是构造预测分析表(Parsing Table)的重要工具,用于解决LL...
根据给定文件的信息,我们可以提炼出与“计算文法的first集合”相关的知识点。下面将对这些知识点进行详细的解析。 ### 第一部分:first集合的概念 在形式语言理论中,特别是上下文无关文法中,一个非终结符的...
《Head First JavaScript源码》是2010年出版的一本中文版JavaScript学习书籍的源码,这本书以其独特的视觉设计和易理解的方式深入浅出地介绍了JavaScript编程语言。JavaScript是一种广泛应用于网页和网络应用的脚本...
《Head First C》是一本备受推崇的C语言学习书籍,其独特的教学方式使得学习过程既有趣又富有成效。书中的内容旨在让初学者能够轻松掌握C语言的基础知识,并逐步建立起对编程逻辑的理解。 C语言是一种强大的、底层...
《Head First Servlet & JSP》是一本非常受欢迎的IT教程,专为准备SCWCD(Sun Certified Web Component Developer)认证的读者设计。本书以其独特的学习风格,深入浅出地介绍了Servlet和JSP(JavaServer Pages)这两...
Head First Python(第2版)是Head First知名书系又一力作,是互联网畅销书《Head First JAVA》《Head First 设计模式》姐妹篇。你是不是想学习Python语言但又不想那么费劲地翻阅手册?利用这本《Head First Python...
编译原理课程设计First集和Follow集生成算法模拟 【问题描述】 设计一个由正规文法生成First集和Follow集并进行简化的算法动态模拟 【基本要求】 动态模拟算法的基本功能是: (1) 输入一个文法G; (2) 输出由...
### Head First Java SharpenSolutions知识点解析 #### 标题:Head First Java SharpenSone 习题解答 - **核心知识点**:本标题指明了文档的主要内容为《Head First Java》一书中的练习题解答。《Head First Java...
在编译原理中,First集和Follow集是用于解析语法的关键概念,特别是在构造LL(1)解析表时。这两个集合都是针对文法中的非终结符的,它们帮助确定文法的解析路径,确保文法的一致性和无二义性。 First集(First Set)...
《Head First Java》是一本非常受欢迎的Java编程学习书籍,其中文高清版为中国的Java初学者提供了方便的学习资源。这本书以其独特的教学方式,通过丰富的图像、幽默的插图和互动性的设计,帮助读者以轻松有趣的方式...
"Head First JavaScript"是一本面向初学者的优秀教材,旨在通过直观、易懂的方式教授JavaScript的核心概念和技术。这本书采用Head First系列的独特教学方法,以图像、故事和游戏等形式,帮助读者更轻松地理解和掌握...
在编译原理中,"first集"和"follow集"是两种重要的概念,它们主要用于分析和构造词法分析器(也称为扫描器或分词器)以及语法分析器(如LL解析器或LR解析器)。这里提供的资料是关于Java版的first集和follow集实现,...
在编译原理中,`FIRST集`和`FOLLOW集`是两个至关重要的概念,它们在解析器设计和实现中起到关键作用。`FIRST集`代表了非终结符可能生成的符号序列的第一个符号,而`FOLLOW集`则表示在某个非终结符后面可能出现的符号...
LL(1)文法求First和Follow集合 LL(1)文法是编译原理中一种常用的文法分析方法,主要用来解决左递归和左因子问题。First集合和Follow集合是LL(1)文法中的两个重要概念。 First集合是指对于给定的文法符号串,可以在...