Java的面向对象性

Java的面向对象性

Java语言是Sun公司开发的新型面向对象程序设计语言,它以简单易学、概念清晰的纯面向对象特性见长,非常适合于学习面向对象程序设计。
Java语言保留了C++的许多面向对象特性,并在函数封装、数组对象化等方面作了大量改进,使其面向对象特性比C++更突出。更可贵的是为适应网络计算的发展需要,Java又增加了分布式、动态性、并行性、可移植性等特性,取消了C++中指针、指针运算等不利于分布式计算的机制,为在分布式环境下开发动态可扩展的应用提供了便利条件。
对面向对象计算模型的支持
一种OOPL(Object Oriented Programming Language,面向对象程序设计语言)至少应支持抽象、封装、继承、多态和动态束定等公认特征,下面依次分析Java语言对以上的特征支持。
1.抽象和封装
客观世界中的对象均具有属性和行为,映射到程序世界中,属性表示数据,行为代表操作。所谓封装,就是用一个自主式框架将数据集和操作集组织在一起,构成一个程序实体,即程序世界中的对象。在面向对象概念中,对象是支持封装的手段,是封装的基本单位。数据集描述对象的状态,对象行为(执行操作)的结果引起状态改变。对象内部的数据和操作可以公有(public)也可以私有(private)。私有的数据和操作只能被对象自身访问,公有的操作和数据则可被其他对象访问。每个对象可以接收一组消息,对象解释一条消息,执行一个相应的操作。一个面向对象程序的执行就是系统中一系列对象之间相互发消息通信的过程。因此,面向对象的程序设计模型可以概括为:程序=对象+消息。
封装和抽象是密不可分的。在Java语言中,对象由类(class)来描述,每个对象均有一个相应的类。类是具有相似特征的对象模板,是对具体对象的抽象。对象通过实例化一个类而得以创建,被创建的对象称为类的一个实例(Instance)。类中封装了对象的属性和方法,对象的属性既可以是常量也可以是其他类的实例,对象的方法用函数和过程来表示。
与C++不同,Java更纯正,即语言的任何方面都是基于消息或基于对象的,所有数据类型,无论简单还是复杂,均为对象类。可以从三个方面来说明Java的纯面向对象特性:首先,Java实现了ANSIC中所有数据类型,并且为这些基本数据类型定义了对象类,如整型int的类为Integer。其次,在Java语言中字符串和数组也是对象,它们分别用字串类(String)和相应类的数组类来描述,例如,如果你定义了A类,则Java自动为你定义A的数组类A[]。最后,同Smalltalk类似,Java语言中的类也是对象,类可以用元类来描述。元类是Java内定义的一种特殊类,是对类的抽象,它可以用来实现Java的动态特性——即时装入类,生成实例。
此外,Java语言可以通过前置修饰符来标明对象属性和方法的可访问程度。其中公共(public)属性和方法可以被任何类的实例访问;友元(friendly)属性和方法只能被同一包(package)中类的实例访问;受保护(protected)的属性和方法只能由对象本身及其子类的实例访问;私有属性和方法只能由对象本身访问。属性和方法的访问修饰符体现了面向对象中的封装原则。
2.继承性
面向对象的继承性意味着在开发新类时可以只说明它与另一个已存在的类的不同之处,新类继承已存在类的属性和方法。在继承层次中,父类也叫基类,子类也叫派生类。一个派生类只有一个基类称为单继承,若有多个基类则称为多继承。如果将基类及其派生类组成的类体系存入库中则形成类库。类库为软件开发带来莫大方便,程序设计的主要工作就是浏览类库,选择合适的类加以重用,这样减少了代码重复,减轻了开发的工作量。
继承是Java语言的核心思想,它的基本类库作为语言自身的一部分而存在。在Java中,无论系统类库中已存在的类还是用户定义的新类都直接或间接地继承于一个公共基类Object。Objetc定义了所有类实例的若干公共的行为:实例间复制、比较以及线程操作等。
Java语言在类之间通过extend关键字实现单继承,一个类仅能有一个基类,因此Java的核心继承体系是树状结构。此外,Java还引入了一种新的语言机制——接口(Interface)。在Java中,接口是一种特殊的抽象类,它仅能声明常量和抽象方法,而没有方法的具体实现。方法的具体实现在实现(Implements)接口的类中定义。一个类除了继承基类外,还可以实现多个接口,并且处在不同继承分枝的类可以实现同一接口,这样就间接地实现了多重继承。
3.多态性和动态束定
一个名字代表多种类型,多种类型的变量,或多个不同语义的函数或过程叫多态。我们经常会遇到不同类型的对象具有相同行为,但行为内容不同的情况,比如汽车和飞机都可以运动,但它们具体运动的方式并不相同,这就是面向对象中的多态。
归纳起来Java主要在四个方面体现多态性:继承、重载(overloading)、覆盖(overriding)和接口。在继承机制中,基类定义的操作适用于类的对象,这种多态也称为包容多态,是最简单的多态方法。象C++一样,Java语言在同一个类中支持方法重载,即方法相同,但参数类型、个数不同。例如,一个Java类可以定义多个构造函数,在实例化中,根据不同参数调用同名方法的不同实现版本,重载也是多态的一种类型。覆盖和重载是完全不同的概念,Java的方法重载在同一个类中,而方法覆盖则在有继承关系的不同类中,即在有继承关系的类之间实现多态。顾名思义,覆盖不仅方法名相同,且变元数目和类型、方法返回类型都相同,即在派生类中重新实现基类的某一方法。此外,Java语言还可以通过接口在没有直接联系的类之间实现多态。前面提到,接口中的方法是抽象方法,有声明而没有具体实现,任何实现接口的类都要具体实现接口的方法。这样,多个实现同一接口的类就有了同名的方法,不同的方法实现,体现了多态性。重载、覆盖和接口实现的多态都是同一方法配备的多个方法体,它们统称为重载多态。
Java语言的动态特性
多数面向对象程序设计语言在系统设计编制阶段都能充分体现OO思想,但却很难将OO延伸至系统运行和维护阶段。这主要是因为多数语言都采用静态链连机制,即在编译时就将组成系统的各模块和类链连组合成一个整体,破坏了系统的模块性。在系统运行和维护阶段,如果某些类进行了修改或升级,整个系统必须重新编译才能利用类新增或修改的功能,未能体现面向对象的优势。此外,随着网络技术的发展,计算环境正迅速由单主机集中式向网络分布式转变。在分布式环境中,系统运行情况更为复杂,维护越发困难,特别是在某些情况下,系统一旦运行一般就不能停止,例如金融机构的联机事务处理系统等。如何在运行中动态的进行系统修改和升级便成为迫切需要解决的问题。
Java语言的动态特性是对面向对象设计的延伸,用Java开发的系统能够适应不断变化的执行环境,这正可以解决上述问题。动态特性的技术核心是滞后联编,滞后联编使Java将OO特点延伸到系统运行阶段。我们知道,Java程序的基本组成单位是类,编译时每个类被分别编译成相应的类文件,这样一个系统由若干个类文件组成,系统的模块性得以保留,在系统运行时,类文件按程序运行需要被动态装载,即插即用(Plug-And-Play)。利用这种特性,系统的支持类修改之后,相应的应用程序不必重新编译,也一样可以利用修改后类的功能。如果类文件是分布在网络环境下,Java也可以利用这种特性在分布式环境中动态维护应用程序及其支持类库之间的一致性。
(陈冲 黎杰)