Java-面向对象的含义

来源:互联网 发布:2016淘宝营业额 编辑:程序博客网 时间:2024/05/16 08:08

以下文字摘录至《UML面向对象设计基础》

Meilir Page-Jones

 

1.封装(encapsulation):将相关的概念组成一个单元,其后可以通过一个名称来引用它。

重复的代码可以放到程序的某个地方,并可以从主程序的不同地方通过一个名字来激活。eg:代码复用(组合+继承)

面向过程封装:由此产生子程序的概念,此时指令的封装被术语化了。

面向对象封装(object-oriented encapsulation):将表示状态的属性和操作包装成一个对象类型,使得对状态的访问或修改只能通过封装提供的接口进行。

一个对象是由一系列属性和操作组成。每个操作是一个过程or函数,对其他对象是可见的,即可被其它对象调用;属性表示对象记忆的信息,它只能通过对象的操作来访问和修改。换言之,其它对象不能直接访问这些属性。其它对象需要访问属性信息只能通过对象的操作来访问;因为只有对象的操作可以读取和修改对象的属性,所以就好像是这些操作以对象的变量为中心形成了一个保护环。

 

2.信息/实现隐藏(information/implementation hiding):使用封装将某些信息or实现方法限制在封装结构内部,限制外部的可见性。

好的封装结果是对公共视角封闭大量的细节。这种封闭有两种形式即信息隐藏和实现隐藏。

信息隐藏:不能被外界察觉的单元内的信息(属性)

实现隐藏:不能被外界察觉的单元内的实现信息(方法)

封装通常提供信息(get(), set()方法)而隐藏实现方法。这点对面向对象十分重要:对象内部变量存储的属性信息的实现方法,与该属性本身的自然计算方法可以不同。例如:机器人对象(通过location操作)告诉我们它所处的位置,但我们并不知道对象内部如何存储它的位置。可能是二维坐标(xCoord, yCoord),或平面向量,或经纬度坐标等等。只要对象能以我们所能接受的方式(eg:字符方式N, E, SW)输出其位置,我们就不关心它是如何存储位置的。

信息/实现隐藏是降低软件复杂性的有效技术。对外部观察者而言,可以将对象看作一个黑箱子。换言之,外部观察者知道对象可以做什么,而不知道对象如何做或对象内部是如何构造的。

 

3.保持状态:对象具有保存状态的能力(状态即对象拥有值的集合)

当传统的过程模块(函数、子程序、过程等)返回到调用者时,不会带来任何负作用,模块运行结束,只是将其结果返回。当同一个模块再次被调用时就像是第一次诞生一样。模块对以前的存在没有任何记忆,就像人类一样对以前的存在一无所知。

但对于对象而言,如机器人对象就知道它的过去。对象在其自身内部将信息保留一段时间。也就是说对象执行结束后并没有死:忠于职守,准备再次运行。

但对象的“保持状态”特性很容易使对象成为垃圾,要进行垃圾回收。

 

4.对象标识(object identity):每个对象都有自己的标识。即每个对象(不考虑其所属类或当前状态)可以作为不同的软件实体被标识、处理的特性。

实际就是变量的栈内存引用堆内存的概念。

 

5.消息(message):发送对象obj1向目标对象obj2发送请求的载体,申请对象obj2的一个方法。

对象通过消息请求另一个对象执行活动。许多消息还具有将消息从一个对象传递给另一个对象的作用。实际就是方法调用。

 

6.(class)

7.继承(inheritance)

 

8.多态性(polymorphism):是一种方法,这种方法使得在多个类中可以定义同一个操作或属性名,并在每个类中可以有不同的实现;也是一种特性,这种特性使得一个属性或变量在不同时期可以表示不同类的对象。

多态是指具有许多形态的特性,正如《异性人》中的情节,宇宙飞船中的全体船员不断被一个可以迅速从一个形体变为另一个形体的异己分子袭击。

假设我们有一个类Polygon,表示二维图形。并为Polygon定义getArea()方法,该方法返回Polygon对象的面积。getArea()的算法非常复杂,因为要考虑不规则的多边形。

再定义Polygon的子类:TrigangleRectangleHexagon。其中TrigangleRectangle继承并覆盖getArea()方法,因为计算TrigangleRectangle面积的方法简单且高效,而计算普通Polygon面积的算法复杂且低效,所以我们不用该算法计算TrigangleRectangle的面积;Hexagon只继承了PolygongetArea()方法。

Trigangle trigangle = new Trigangle();

Rectangle rectangle = new Rectangle();

Hexagon hexagon = new Hexagon();

Polygon polygon = new Polygon();

trigangle.getArea(); // Trigangle中的getArea()将被执行

rectangle.getArea(); // Rectangle中的getArea()将被执行

hexagon.getArea(); // Polygon中的getArea()将被执行,因为Hexagon只继承而没有覆盖PolygongetArea()方法

polygon.getArea(); // Polygon中的getArea()将被执行

面向对象环境经常通过动态绑定实现多态性。在这种环境中,当消息发送后,在运行期间尽可能靠近地检查消息的目标对象。

动态绑定(dynamic binding)(或运行时绑定或最后绑定):一种在运行时(而不是在编译时)确定被执行代码的技术。

覆盖(overriding):父类定义的方法在其某子类中被重新定义。

上诉例子的getArea()即说明了覆盖,getArea()原本是在Polygon中定义,在TriangleRectangle中被覆盖。TriangleRectangle中的操作与Polygon操作的名字相同,但算法不同。

你可能会偶尔使用overriding在子类中取消父类的一个操作。但如果需要大量使用overriding操作,源于父类/子类的层次结构可能不可靠。

与多态性相关的一个概念是重载(overloading),请不要与overriding混淆。

名字or符号的重载(overloading):在同一个类中定义的几个操作(或操作符)都具有同一类的名字或符号,我们称该名字or符号为重载。

多态性和重载都要求在运行时(即动态绑定)选择指定的操作。到底哪个才是目标对象(即将被执行操作的特定实现),只有到运行时才知道。

多态性和重载的一般区别在于:多态性允许使用相同的操作名在不同的类中定义不同的操作;而重载允许相同的操作名在相同类中定义几次,通常是在相同的名字空间。

选择哪个多态性操作依赖于消息发送的目标对象类(通过动态绑定实现)。但对于重载操作而言,问题是如何在运行时将正确的程序绑定到操作名? 答案是使用消息参数(参数的类型or数目)

 

9.一般性(genericity):在多个类内部可以调用某模板类的结构,该模板类具有一般性。

例如“堆排序”算法模块就具有一般性,可以用于年龄排序、价格排序或姓名首字母排序,这是狭义一般性。实际就是封装功能模块的概念。《Thinking in Java》中讲到的代码复用:组合+继承,实际就是广义的一般性。

狭义一般性常用在面向对象中的容器类(eg:建立汽车容器,这个容器中可以存放轿车、SUVMPV、救护车或卡车)。尽管不是必须使用一般性为容器类编写可重用代码,但它确实比复制的程序or将任意类的对象混合在同一个容器的脆弱设计要好。

 
原创粉丝点击