Java编程指南:基础知识、类库应用及案例设计
上QQ阅读APP看书,第一时间看更新

2.3 Java对象

在Java语言程序中,Java类只有实例化(创建对象或称实例)才能被使用。一个对象的生命周期被分为3个阶段:对象的创建、使用和清除。

2.3.1 对象的创建

创建一个对象首先需要声明一个类变量,该变量的数据类型为已经定义好的类,但是声明类变量并不产生该类型的对象,创建对象需要使用Java关键字new,创建对象的过程在Java中称为实例化,实例化后的类变量才是一个具有实际意义的Java对象,在Java程序中方可使用。

声明类变量和创建Java对象的语法格式为:

语句“ClassName ObjectName;”是声明一个类型为ClassName的变量名为ObjectName的变量,它同声明基本数据类型的变量是一样的。声明一个基本数据类型变量后,Java程序运行时,Java虚拟机会为基本数据类型变量分配存储器,并可以对该变量进行读、写等操作,但是,当一个变量被声明为类变量时,Java虚拟机是不会为类变量分配存储器的,即一个类变量在计算机存储器中没有实际内容,当需要使用类变量时,一定要使用Java关键字new为类变量分配存储器。new为类变量创建并占用存储器空间,当类变量通过创建(new)后就会成为具有实际内容的“变量”。在Java语言体系中,new创建后的“变量”被称为“对象”,创建的过程被称为“实例化”一个类变量。

在Java应用程序中使用的正是“对象”,因此,类变量的声明被称为“为对象建立一个引用”,真正要使用的对象并不存在,需要使用new创建对象。声明类变量可以在类中任何地方进行,但是创建一个对象需要在方法体中进行,因为一个类变量等于(=)某一个值,即应用new创建为对象是一种操作,操作一定要在方法体中实现,而不是在整个类中的任何地方都可以实现的。

【示例2-5】 声明类变量并创建对象。

一个类可以声明多个不同的类变量,new可以为它们创建不同的应用对象,这些对象在计算机存储器中是相互独立的,彼此之间互不影响。

【示例2-6】 声明两个类变量并创建两个对象。

声明类变量和创建Java对象还有一种语法格式,将分别进行的声明类变量和创建Java对象合二为一,其语法格式为:

该语法格式与分别声明类变量和创建Java对象的语法格式是等值的,该格式可在类中任何地方创建一个对象,而一个已经声明的类变量则需要在方法体中创建为对象。

【示例2-7】 应用不同的语法格式创建对象。

2.3.2 构造方法的使用

关键字new用于创建对象,在创建对象的语法格式中,关键字new后边的语句是指明调用类的一个构造方法来创建对象,创建一个对象首先被调用的是类的构造方法,因此,一个类要具有构造方法才能被创建,在Java体系中所有的类都有默认的构造方法,即使在类中并没有显现定义构造方法,但该类是继承了父类的构造方法,因为所有的Java类都有继承关系。

构造方法是用于为对象确定一个期望的状态,例如对一个类中的某些数据成员进行初始化操作等,构造方法只能在创建对象时被调用一次,它不能被应用程序中的其他方法调用。

类的构造方法一定是被修饰为public,创建对象是Java虚拟机完成的,Java虚拟机需要为对象分配其所占有的存储器空间,同时需要初始化对象,因此,Java虚拟机是在应用程序外部调用类的构造方法为对象进行初始化操作的,如果构造方法不被修饰为public,则Java虚拟机无法调用构造方法,也就不能创建该类的类对象了。

一个类可以定义多个构造方法,多个构造方法是由不同的输入参数(形式参数)区分的,当通过该类创建对象时,需要指明创建该对象使用的构造方法。

【示例2-8】 应用同一个类中的两个不同的构造方法创建两个对象。

构造方法完成了创建对象时的初始化工作,它只被执行一次,在创建对象时对象需要的初始化操作代码尽可能地放到构造方法中,它可以避免在生成对象后还要再调用对象的另外的其他初始化方法。

2.3.3 对象的使用

对象的使用主要是引用对象的成员变量和方法,运算符“.”可以实现对一个对象中的变量的访问和方法的调用,被引用的变量和方法可以通过设定的访问权限允许或禁止其他对象的访问和调用。

访问对象的某个变量的语法格式为:

调用对象的某个方法的语法格式为:

objectReference是一个对象,它可以是一个已生成的对象,也可以是能够生成对象引用的表达式。

【示例2-9】 类定义和使用类创建对象以及应用对象的程序实例。Operation是一个实现加、减、乘、除操作的类,程序代码为:

Sample类与Operation类在同一个编译单元中,Sample类是应用Operation类创建op对象,通过op对象中的方法完成加、减、乘、除的运算,程序代码为:

在上述程序中,输出显示语句System.out.println()就是通过“.”运算符调用System类的out静态标准输出流(PrintStream)对象中的println()方法,System类是java.lang基础类库提供的,println是标准输出流类定义的用于显示文字的方法。

【示例2-10】 关于对象中变量访问权限的程序示例。同理,类中方法getS_Kind()和setS_Kind()调用的权限与变量s_Name访问权限是一样的。Animal是一个定义动物类的程序:

下面的Sample源程序是创建一个Animal类的类对象ox,当ox被创建后,通过运算符“.”操作对象ox中的变量s_Name以及调用对象ox中的setS_Kind()和getS_Kind()方法,程序代码为:

Sample类和Animal类同属一个编译单元,在Animal类中,s_Name变量的访问权限被修饰为public,因此,该变量是对外开放的,而s_Kind变量的访问权限被修饰为private,不对外开放,如果要访问s_Kind变量,需要通过setS_Kind()“写”和getS_Kind()“读”方法进行读、写操作。

在一个应用程序中,对外开放的变量存在着安全隐患,在Java编程时不建议使用对外开放的变量,应尽可能使用具有private属性的变量,通过方法操作变量,以达到确保类中变量的安全性。例如,在上述程序中的s_Kind变量,由于setS_Kind()和getS_Kind()方法被同时修饰为public,因此,s_Kind变量为可“读”、可“写”型变量,当setS_Kind()方法被修饰为private、而getS_Kind()方法被修饰为public时,s_Kind变量就成为只“读”型变量,同理,当getS_Kind()方法被修饰为private、而setS_Kind()方法被修饰为public时,s_Kind变量就成为只“写”型变量,当getS_Kind()和setS_Kind()方法同时被修饰为private时,s_Kind变量则为不可“读”、不可“写”型变量,通过方法操作变量可以控制对变量的读、写模式。另外,getS_Kind()方法被称为s_Kind变量的获取器,setS_Kind()方法被称为s_Kind变量的设置器。

【示例2-11】 通过方法返回值引用对象成员的示例。方法DisplayString()的返回值为复合数据类型(Display类),其返回值为一个Display对象,即方法DisplayString()返回的是一个对象d,通过方法的返回值引用对象中成员的程序代码为:

当一个方法被要求有多个返回值返回时,可以定义该方法的返回类型为复合数据类型(类),通过复合数据类型实现该方法的多个返回值。

2.3.4 对象的清除

在Java运行管理系统中,使用new运算符为对象或变量分配存储空间,但程序设计者不用刻意在使用完对象或变量后,删除该对象或变量收回它所占用的存储空间,因为Java语言运行系统已经设计了“无用单元自动收集器”,通过“无用单元自动收集器”周期性地释放无用对象所使用的存储空间,完成对象的清除。

Java运行系统的“无用单元自动收集器”自动扫描对象的动态内存区,对被引用的对象加标记,然后把没有引用的对象作为垃圾收集起来并且释放它,释放内存是系统自动处理的,该收集器使得系统内存的管理变得简单、安全。

“无用单元自动收集器”不会释放正在引用的对象,只释放那些不再被引用的对象的存储空间,它使得程序设计者完全从系统存储管理中解脱出来,不需考虑释放内存的问题。

另外,Java语言系统也为程序设计者提供了清除对象的语句,当一个对象不被使用时,可以为该对象赋予null值。

【示例2-12】 当op对象使用完毕后将其赋为null值,即将op对象从内存中清除掉,释放其占用的存储空间。

2.3.5 Java类和对象的关系

Java类和对象的关系为:类是用来定义对象的状态和行为的模板,对象是类的一个具体的实例。例如,在建造房屋时需要有图纸,根据图纸建造一个或多个一样的房屋,“图纸”相当于类,而房屋则是对象,又如,自行车制造商可以一遍又一遍地重复使用相同的图纸(类)制造大量的自行车(对象)。对软件程序员而言,用相同的代码(类)可以一遍又一遍地建立对象,在应用软件中,类是描述现实世界的蓝图,对象是现实世界的电子模型,对象是根据类创建出来的。

使用类和对象是面向对象编程的基本原则之一,类和对象的好处在于它们使开发者能够处理现实世界中的任何问题,并可以方便地对需要用来解决该问题的软件部件进行分类和定义,任何一个对象(例如房屋)一定能被分成一些子部件(例如地板、屋顶、地基、墙等),使用类和对象的做法与现实世界中通常解决问题的方法是非常相像的,一个问题从不被作为一个整体来对付,总是被分成一些可以控制的部分,每一个这样得出的对象再被细化并可能分成更多的对象,分类过程进行到一定程度便结束,每个对象将被赋予一定的行为特征,这样就使得一个整体问题得到了细化、模块化以及简单化。

在面向对象编程中,对象提供了模型化以及信息隐藏等好处,而类又提供了代码重用等好处,所以,面向对象的设计思想更适用于大型软件的开发工作。