《Java程序案例教程》课件第5章_第1页
《Java程序案例教程》课件第5章_第2页
《Java程序案例教程》课件第5章_第3页
《Java程序案例教程》课件第5章_第4页
《Java程序案例教程》课件第5章_第5页
已阅读5页,还剩156页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5章类的基本形式5.1面向对象程序设计的基本概念

5.2类与对象

5.3类的封装性

5.4在类内部调用方法

5.5引用数据类型的传递5.6匿名对象5.7构造方法5.8对象的比较5.9this关键字的使用5.10static关键字的使用5.11构造方法的私有5.12对象数组的使用

5.1面向对象程序设计的基本概念

早期的程序设计经历了“面向问题”、“面向过程”的阶段,随着计算机技术的发展,以及所要解决问题的复杂性的提高,以往的程序设计方法已经不能适应这种发展的需求,于是从20世纪70年代开始,相继出现了多种面向对象的程序设计语言(如图5-1所示),并逐渐产生了面向对象的程序设计方法。面向对象的程序设计涉及对象、封装、类、继承及多态等基本概念。图5-1计算机语言的发展过程5.1.1对象

何谓面向对象呢?面向对象程序设计是将人们认识世界过程中普遍采用的思维方法应用到程序设计中。对象是现实世界中存在的事物,它们是有形的,如某个人、某种物品,也可以是无形的,如某项计划、某次商业交易。对象是构成现实世界的一个独立单位,人们对世界的认识,是从分析对象的特征入手的。

对象的特征分为静态特征和动态特征两种。静态特征指对象的外观、性质、属性等;动态特征指对象具有的功能、行为等。客观事物是错综复杂的,但人们总是从某一目的出发,运用抽象分析的能力,从众多特征中抽取最具代表性、最能反映对象本质的若干特征加以详细研究。人们将对象的静态特征抽象为属性,用数据来描述,在Java语言中称之为变量;人们将对象的动态特征抽象为行为,用一组代码来表示,完成对数据的操作,在Java语言中称之为方法。一个对象由一组属性和一组对属性进行操作的方法构成。

5.1.2类

具有相同属性及相同行为的一组对象称为类。广义地讲,具有共同性质的事物的集合称为类。在面向对象程序设计中,类是一个独立的单位,它有一个类名,其内部包括成员变量,用于描述对象的属性,还包括类的成员方法,用于描述对象的行为。在Java程序设计中,类被认为是一种抽象数据类型,这种数据类型不但包括数据,还包括方法。这大大扩充了数据类型的概念。

类是一个抽象的概念,要利用类的方式来解决问题,必须用类创建一个实例化的类对象,然后通过类对象去访问类的成员变量,去调用类的成员方法来实现程序的功能。这类同于“汽车”本身是一个抽象的概念,只有使用了一辆具体的汽车,才能感受到汽车的功能。一个类可创建多个类对象,它们具有相同的属性模式,但可以具有不同的属性值。Java程序为每一个类对象都开辟了内存空间,以便保存各自的属性值。

面向对象的程序设计具有如下三个主要特征:

(1)封装性;

(2)继承性;

(3)多态性。5.1.3封装性

封装是面向对象的方法所应遵循的一个重要原则。它有两个含义:一是指把对象的属性和行为看成一个密不可分的整体,将这两者“封装”在一个不可分割的独立单位(即对象)中;另一层含义指“信息隐蔽”,把不需要让外界知道的信息隐藏起来。有些对象的属性及行为允许外界用户知道或使用,但不允许更改,而另一些属性或行为则不允许外界知晓,或只允许使用对象的功能,而尽可能隐蔽对象的功能实现细节。封装机制在程序设计中表现为,把描述对象属性的变量及实现对象功能的方法合在一起,定义为一个程序单位,并保证外界不能任意更改其内部的属性值,也不能任意调动其内部的方法。封装机制的另一个特点是:为封装在一个整体内的变量及方法规定了不同级别的“可见性”或访问权限。

5.1.4继承性

继承是面向对象方法中的重要概念,并且是提高软件开发效率的重要手段。首先拥有反映事物一般特性的类,然后在其基础上派生出反映特殊事物的类。例如,已有汽车的类,该类中描述了汽车的普遍属性和行为,进一步再产生轿车的类,轿车的类继承于汽车类,轿车类不但拥有汽车类的全部属性和行为,还增加了轿车特有的属性和行为。在Java程序设计中,已有的类可以是Java开发环境所提供的一批最基本的程序—类库。用户开发的程序类继承这些已有的类。这样现在类所描述过的属性及行为,即已定义的变量和方法,在继承产生的类中完全可以使用。被继承的类称为父类或超类,而经继承产生的类称为子类或派生类。根据继承机制,派生类继承了超类的所有成员,并相应地增加了自己的一些新的成员。面向对象程序设计中的继承机制大大增强了程序代码的可复用性,提高了软件的开发效率,降低了程序产生错误的可能性,也为程序的修改扩充提供了便利。若一个子类只允许继承一个父类,称为单继承;若允许继承多个父类,称为多继承。目前许多面向对象程序设计语言不支持多继承。Java语言通过接口(interface)的方式来弥补由于Java不支持多继承而带来的子类不能享用多个父类成员的缺憾。5.1.5类的多态性

多态是面向对象程序设计的又一个重要特征。多态是指允许程序中出现重名现象。Java语言中含有方法重载与成员覆盖两种形式的多态。方法重载是指在一个类中,允许多个方法使用同一个名字,但方法的参数不同,完成的功能也不同。成员覆盖是指子类与父类允许具有相同的变量名称,但数据类型不同,允许具有相同的方法名称,但完成的功能不同。

多态的特性使程序的抽象程度和简捷程度更高,有助于程序设计人员对程序的分组进行协同开发。 5.2类与对象

面向对象的编程思想力图使在计算机语言中对事物的描述与现实世界中该事物的本来面目尽可能地一致,类(class)和对象(object)就是面向对象方法的核心概念。

类是对某一类事物的描述,是抽象的、概念上的定义;对象是实际存在的该类事物的个体,因而也称实例(Instance)。图5-2就是一个说明类与对象的典型范例。

图5-2中,汽车设计图就是“类”,由这个图纸设计出来的若干汽车就是按照该类产生的“对象”。图5-2类与对象的实例化说明5.2.1类的声明

在使用类之前,必须先定义它,然后才可利用所定义的类来声明变量,并创建对象。类定义的语法如下:程序说明:

(1)用class声明了一个名为Person的类,这里Person是类的名称。

(2)第3、4行声明了两个属性name和age,name为String型(字符串类型),age为int型(整型)。

(3)第5~8行声明了一个talk()方法,此方法用于向屏幕打印信息。

为了更好地说明类的关系,请参见图5-3。图5-3Person类图5.2.2创建新的对象

在实际中单单有类是不够的,类提供的只是一个模板,必须依照它创建出对象之后才可以使用。下面定义了由类产生对象的基本形式:

类名对象名=new类名();

创建属于某类的对象,需要通过下面两个步骤来实现:

(1)声明指向“由类所创建的对象”的变量。

(2)利用new创建新的对象,并指派给先前所创建的变量。

如果要创建Person类的对象,可用下列的语句来实现:

Personp; //先声明一个Person类的对象p

p=newPerson(); //用new关键字实例化Person类的对象p

当然也可以用下面这种形式来声明变量:

Personp=newPerson(); //声明Person对象p并直接实例化此对象

对象只有在实例化之后才能被使用,而实例化对象的关键字就是new。对象实例化过程如图5-4所示。图5-4Person类对象的实例化过程由图5-4可以看出,当语句执行到Personp时,只是在栈内存中声明了一个Person的对象p,但是这时p并没有在堆内存中开辟空间,所以这时的p是一个未实例化的对象,用new关键字实际上就是开辟堆内存,把堆内存的引用赋给了p,这时的p才称为实例化对象。

如果要访问对象中的某个成员变量或方法,可以通过下面语法来实现:

访问属性:对象名称.属性名。

访问方法:对象名称.方法名()。输出结果:

我是:张三,今年:25岁

程序说明:

(1)第6行声明了一个Person类的实例对象p,并直接实例化此对象。

(2)第7、8行给p对象中的属性赋值。

(3)第9行调用talk()方法,在屏幕上输出信息。

参照上述程序代码与图5-5的内容即可了解到Java是如何对对象成员进行访问操作的。图5-5对Person对象p的访问操作过程5.2.3创建多个新对象

在例5-3的程序中,只建立了一个Person的对象p,如果需要创建多个对象,则可以依照由类产生对象的基本形式产生多个对象。

【例5-4】

TestPersonDemo1.java。程序说明:

(1)第1~9行声明了一个新的类Person,类中有name、age两个属性,还有一个talk()方法用于输出信息。

(2)第14~15行声明了Person的两个实例对象p1、p2。

(3)第17、18行给p1对象的属性赋值。

(4)第20、21行给p2对象的属性赋值。

(5)第23、24行分别用p1、p2调用Person类中的talk()方法,用于在屏幕上打印信息。

上述程序首先声明了两个对象p1和p2,之后分别为p1与p2赋值。可以发现,p1与p2赋的值互不影响,此关系可由图5-6表示出来。图5-6Person中p1与p2的内存分配图案例1对象组合案例

【案例描述】

编写一个Circle类,该类的对象可以计算圆的面积。

【代码与注释】

程序名称为Circle.java。

程序代码如下: 5.3类 的 封 装 性

【例5-5】

TestPersonDemo2.java。输出结果:

我是:张三,今年:-25岁

程序说明:

(1)第1~9行声明了一个新的类Person,类中有name、age两个属性,还有一个talk()方法用于输出信息。

(2)第15行声明并实例化Person的对象p。

(3)第17~21行分别为p对象中的属性赋值,并调用talk()方法。

由上面的程序可以看出,在程序的第19行将年龄(age)赋值为-25,这明显是一个不合法的数据,最终程序在调用talk()方法时才会打印出这种错误的信息。程序说明:

(1)第1~9行声明了一个新的类Person,类中有name、age两个属性,还有一个talk()方法用于输出信息。与前面不同的是,这里的属性在声明时前面都加上了private关键字。

(2)第15行声明并实例化Person类的对象p。

(3)第17~21行分别为p对象中的属性赋值,并调用talk()方法。

可以看出,本程序与例5-5除了在声明属性上有些区别外,并没有其他区别,而就是这一个小小的关键字,导致程序连编译都无法通过,所提示的错误为:属性(name、age)为私有的,所以不能由对象直接进行访问。程序说明:

(1)第9~25行加入了一些setXxx()、getXxx()方法,主要用来设置和取得类中的私有属性。

(2)第13~17行设置年龄时在程序中加了判断语句,如果传入的数值大于0,则将值赋给age属性。

(3)第35行调用了Person类中的setName()方法,并赋值为“张三”。

(4)第37行调用了setAge()方法,同时传进了一个-25的不合理年龄。

可以发现在本程序中,传进了一个-25的不合理数值,这样在设置Person中的属性时因为不满足条件而不能被设置成功,所以age的值依然为自己的默认值0。这样在输出时可以发现,那些错误的数据并没有被赋到属性上,而只输出了默认值。用private声明的属性或方法只能在其类的内部被调用,而不能在类的外部被调用。读者可以先暂时简单理解为:在类的外部不能用对象去调用private声明的属性或方法。下面程序修改自例5-7,在这里将talk()方法封装了起来。

【例5-8】

TestPersonDemo4.java。程序说明:

(1)第5行将talk()方法用private来声明。

(2)第9~25行加入了一些setXxx()、getXxx()方法,主要用来设置和取得类中的私有属性。

(3)第13~17行设置年龄时在程序中加了判断语句,如果传入的数值大于0,则将值赋给age属性。

(4)第35行调用了类Person中的setName()方法,并赋值为“张三”。

(5)第37行调用了setAge()方法,同时传进了一个不合理的年龄-25。 5.4在类内部调用方法

在一个Java程序中是可以通过对象去调用类中的方法的,当然类的内部也能互相调用各自的方法。例如,下面的程序修改自以前的程序代码,新增加了一个公有的say()方法,并用这个方法去调用私有的talk()方法。

【例5-9】

TestPersonDemo5.java。输出结果:

我是:张三,今年:30岁

程序说明:

(1)第9~12行声明公有方法say(),此方法用于调用类内部的私有方法talk()。

(2)第42行调用Person类中的say()方法,其实也就是调用Person类中的talk()方法。 5.5引用数据类型的传递

Java中使用引用来取代C++ 中的指针,那么什么是引用呢?Java又是怎样通过引用来取代C++ 中的指针的呢?

【例5-10】

TestRefDemo1.java。

程序说明:

(1)第1~5行声明Person类,有name与age两个属性。

(2)第11、13行分别声明两个Person的对象p1和p2,但这两个对象在声明时都同时赋值为null,表示此对象未实例化。

(3)第15行对对象p1进行实例化。

(4)第17、18行分别为p1对象中的属性赋值。

(5)第20行将p1的引用赋给p2,此时相当于p1与p2都同时指向同一块堆内存。

(6)第22、23行分别调用和p2.age,输出p2对象中的属性。

(7)第24行把p1对象赋值为null,表示此对象不再引用任何内存空间。

程序执行到第24行时,实际上p1断开了对其之前实例化对象的引用,而p2则继续指向p1原先的引用。

由上述程序可以看出,在程序中并未用new关键字为对象p2实例化,到最后依然可以用与p2.age方式输出属性的内容,且内容与p1对象中的内容相似。也就是说,在上述程序中p2是通过p1对象实例化的,或者说p1将其自身的引用传递给了p2,如图5-7所示。图5-7引用数据类型的传递如果在程序最后又加了一段代码,令p2=null,则之前由p1创建的实例化对象不再有任何对象使用它,此对象称为垃圾对象,如图5-8所示。图5-8垃圾对象的产生所谓垃圾对象,就是指程序中不再使用的对象引用。

【例5-11】TestRefDemo2.java。程序说明:

(1)第1~4行声明一个名为Change的类,其有一个属性x。

(2)第9行实例化了一个Change类的对象c。

(3)第10行将对象c中的x属性赋值为20。

(4)第11行调用fun()方法将对象c传递到方法中。

(5)第14~17行声明fun方法,接收参数类型为Change类型。

(6)第16行将对象c1中的x属性赋值为25。

程序最后的输出结果为“x=25”,而程序只有在fun()方法中才将x的值赋为25,为什么方法完成之后值依然被保留了下来呢?读者可以发现在程序第14行,fun()方法接收的参数是Changec1,也就是说fun()方法接收的是一个对象的引用。所以在fun方法中所做的操作会影响原先的参数。可以参考图5-9来了解整个过程。图5-9操作过程

5.6匿名对象

顾名思义,匿名对象就是没有明确声明的对象。读者也可以简单地理解为只使用一次的对象,即没有任何一个具体的对象名称引用它。

【例5-12】TestNoName.java。程序说明:

(1)第1~9行声明了Person类,其有name与age两个私有属性,并分别赋了初值。

(2)第14行声明了Person匿名对象,调用Person类中的talk()方法。

从程序中可以看出,用newPerson()声明的对象并没有赋给任何一个Person类对象的引用,所以此对象只使用了一次,之后就会被Java的垃圾收集器回收。

5.7构造方法

1.构造方法的定义

在Java程序中,构造方法所完成的主要工作是帮助新创建的对象赋初值。构造方法可视为一种特殊的方法,它的定义方式与普通方法类似,其语法如下:在使用构造方法时应注意以下几点:

(1)它具有与类名相同的名称。

(2)它没有返回值。

构造方法没有返回值,其名称必须与类的名称相同,它的调用时机与一般方法不同。一般方法是在需要时才调用,而构造方法则是在创建对象时便自动调用,并执行构造方法的内容。因此,构造方法无需在程序中直接调用,而是在对象产生时自动执行。

基于上述构造方法的特性,可利用它来对对象的数据成员进行初始化赋值。所谓初始化,就是为对象赋初值。

下面的程序说明了构造方法的使用。

【例5-13】TestConstruct.java。从上述程序中读者不难发现,在类中声明的构造方法会在实例化对象时自动调用。读者可能会问,在之前的程序中用同样的方法来产生对象,但是在类中并没有声明任何构造方法,而程序不也一样正常运行了吗?实际上,读者在执行javac编译Java程序时,如果在程序中没有明确声明构造方法,则系统会自动为类加入一个无参的且什么都不做的构造方法,类似于下面代码:

publicPerson(){}

所以,之前的程序虽然没有明确声明构造方法,也是可以正常运行的。

2.构造方法的重载

在Java中,不仅普通方法可以重载,构造方法也可以重载。只要构造方法的参数个数不同,或是类型不同,便可定义多个名称相同的构造方法。这种做法在Java中是常见的。

【例5-14】TestConstruct1.java。

(3)第20行调用Person类中含有两个参数的构造方法(newPerson("张三",25)),同时将姓名和年龄传到类中,分别为各个属性赋值。

(4)第21行调用Person类中的talk()方法,并打印信息。

从上述程序可以看出,构造方法的基本作用就是为类中的属性初始化,在程序产生类的实例对象时,将需要的参数由构造方法传入,之后再由构造方法为其内部的属性进行初始化。这是在一般开发中经常使用的技巧,但是这里有一个问题是读者应该注意的,请看下面的程序。

【例5-15】TestConstruct2.java。可以看出,在编译程序第20行(Personp=newPerson())时发生了错误,这个错误说找不到Person类的无参构造方法。前面曾经提过,如果程序中没有声明构造方法,程序就会自动声明一个无参的且什么都不做的构造方法,可是现在却发生了找不到无参构造方法的问题,这是为什么呢?读者可以发现第5~10行已经声明了一个含有两个参数的构造方法。在Java程序中只要明确声明了构造方法,则默认的构造方法将不会被自动生成。要解决这一问题,只需要简单修改一下Person类即可,可以在Person类中明确地声明一无参的且什么都不做的构造方法。

【例5-16】TestConstruct2.java。 5.8对 象 的 比 较

对象间的比较有两种方式,即“==”运算符与equals()方法。“==”操作符用于比较两个对象的内存地址值是否相等,equals()方法用于比较两个对象的内容是否一致。

【例5-17】TestEquals.java。由程序的输出结果可以看出,str1不等于str2。有些读者可能会问,str1与str2的内容完全一样,为什么会不等于呢?程序第5行和第6行分别实例化了String类的两个对象,此时这两个对象指向不同的内存空间,所以它们的内存地址是不一样的。这时程序中用的是“==”比较,比较的是内存地址值,所以输出str1!=str2。程序第7行将str2的引用赋给str3,这时就相当于str3也指向了str2的引用,这两个对象指向的是同一内存地址,所以比较值的结果是str2==str3。

那么该如何去比较其中的内容呢?这就需要采用另外一种方式—equals()方法。

【例5-18】TestEquals1.java。输出结果:

str1equalsstr2

str2equalsstr3

可以看出,在程序中将比较方式换成了equals(),而且调用equals()方法的是String类的对象,所以可知equals()是String类中的方法。特别注意:“==”用于比较内存地址值,“equals()”用于比较内容。

下面两种String对象的声明方式到底有什么不同?

Stringstr1=newString("java");

Stringstr2="java";

下面先来看一个例子。

【例5-19】StringDemo.java。图5-10String对象的声明与使用由图5-10中可以看出,“java”这个字符串在内存中开辟一个空间,而str1与str3又同时指向同一内存空间,所以即使str1与str3是分两次声明的,但最终都指向了同一内存空间。str2用new关键字来开辟空间,所以单独占有自己的一个内存空间。

另外,要注意的是,String对象的内容一旦声明,就不能轻易改变。如果要改变一个String对象的值,第一步要做的是将原有的String引用断开,之后再开辟新的内存空间,而且如果用new关键字开辟String对象的内存空间,则实际上就开辟了两个内存空间,如图5-11所示。图5-11String对象内容的改变 5.9this关键字的使用

1.this的本质

在整个Java的面向对象程序设计中,this是一个比较难理解的关键字,它表示当前对象,而所谓的当前对象,就是指调用类中方法或属性的那个对象。

【例5-20】Person.java。

Person-1.java这段代码与Person.java的不同之处在于在第7、8行分别加上了this关键字。此时的和this.age就分别代表类中的name与age属性,这时再完成赋值操作,就可以清楚地知道谁赋值给谁。完整的程序代码如下例所示。

【例5-22】TestJavaThis.java。程序说明:

(1)第1~14行声明了一个名为Person的类。

(2)第5~9行声明Person类的一个构造方法。此构造方法的作用是为类中的属性赋初值。为了更好地说明this是表示当前对象的,下面再举一个例子:判断两个对象是否相等,在这里假设只要姓名、年龄都相同就为同一个人,否则不是同一个人。程序说明:

(1)第1~21行声明了一个名为Person的类,其中有一个构造方法与一个比较方法。

(2)第10~20行在Person类中声明了一个compare方法,此方法接收Person实例对象的引用。

(3)第12行比较姓名和年龄是否同时相等。

(4)第28行由p1调用compare方法,将p2传入到compare方法之中,所以在程序中第12行的就代表,this.age就代表p1.age,而传入的参数p2则被compare方法中的参数p表示。

由此不难理解,this表示当前对象这一重要概念,所以程序最后输出了“相等,是同一人!”的正确判断信息。

2.用this调用构造方法

如果要在程序中用某一构造方法调用另一构造方法,可以用this来实现,具体的调用形式如下:

this();

【例5-24】TestJavaThis1.java。程序说明:

(1)第1~17行声明一个名为Person的类,类中声明了一个无参和一个有参两个构造方法。

(2)第12行使用this调用本类中的无参构造方法。

(3)第22行声明一个Person类的匿名对象,调用了有参的构造方法。

从上述程序可以看出,在第22行虽然调用了Person中有两个参数的构造方法,但是由于第12行使用了this调用本类中的无参构造方法,所以程序先去执行Person中的无参构造方法,之后再去继续执行其他构造方法。如果把this调用无参构造方法的位置任意调换,则可以在任何时候调用构造方法吗?实际上这样理解是错误的。构造方法是在实例化一对象时被自动调用的,也就是说在类中的所有方法中只有构造方法是被优先调用的,所以使用this调用构造方法必须也只能放在构造方法的第一行。下面的程序就是一个错误的程序。 5.10static关键字的使用

5.10.1静态变量

在程序中如果用static声明变量,则此变量称为静态变量。那么什么是静态变量呢?使用静态变量又有什么好处呢?

【例5-25】TestStaticDemo1.java。输出结果:

我是:张三,今年:25岁,来自:中国

我是:李四,今年:30岁,来自:中国

我是:王五,今年:35岁,来自:中国

程序说明:

(1)第1~16行声明一个名为Person的类,含有三个属性:name、age、city。

(2)第6~11行声明Person类的一个构造方法,此构造方法分别为各属性赋值。

(3)第12~15行声明一个talk()方法,此方法用于返回用户信息。

(4)第21~23行分别实例化三个Person对象。

(5)第24~26行分别调用类中的talk()方法输出用户信息。

由上面的程序可以发现,所有的Person对象都有一个city属性,而且所有的属性也全部相同,如图5-12所示。图5-12static变量内存示意图读者可以试着想一想,现在假设程序产生了50个Person对象,如果想修改所有人的city属性,那么是否就要调用50遍city属性进行重新修改呢?显然这样太麻烦了。在Java中提供了static关键字,用它来修饰类的属性后,则此属性就是公共属性。将TestStaticDemo1.java程序稍作修改就形成了TestStaticDemo2.java,如下所示。

【例5-26】TestStaticDemo2.java。程序说明:

(1)第1~15行声明一个名为Person的类,含有三个属性:name、age、city。其中,city为static类型

(2)第6~10行声明Person类的一个构造方法,此构造方法的作用是分别为name、age属性赋值。

(3)第11~14行声明一个talk()方法,此方法用于返回用户信息。

(4)第20~22行分别实例化三个Person对象。

(5)第23~25行分别调用类中的talk()方法,输出用户信息。

(6)第28行修改了p1中的city属性。从上面的程序中可以发现,程序只在第28行修改了city属性,而且只修改了一个对象的city属性,但再次输出时,发现全部对象的city值都发生了一样的变化,这就说明了用static声明的属性是所有对象共享的,如图5-13所示。图5-13static变量的使用从图5-13中可以看出,所有的对象都指向同一个city属性,只要其中有一个对象修改了city属性的内容,则所有对象都会被同时修改。

另外,需要注意一点,用static方式声明的属性也可以用类名直接访问。例如,要想修改city属性中的内容,则可以用如下方式:

Person.city="美国";

所以有些书上也把用static类型声明的变量称为“类变量”。既然static类型声明的变量是所有对象共享的内存空间,也就是说无论最终有多少个对象产生,也都只有一个static类型的属性,那么可不可以用它来计算类到底产生了多少个实例对象呢?读者可以想一想,只要一个类产生一个新的实例对象,就都会去调用构造方法,所以可以在构造方法中加入一些计数操作,如下面的程序:5.10.2静态方法

static既可以在声明变量时使用,也可以用其来声明方法。用它声明的方法有时被称为“类方法”。

【例5-27】TestStaticDemo4.java。程序说明:

(1)第1~19行声明一个名为Person的类,类中含有一个static类型的变量city,并对此对象进行了封装。

(2)第15~18行声明一个static类型的方法,此方法也可以用类名直接调用,用于修改city属性的内容。

(3)第32行由Person调用setCity()方法,对city的内容进行修改。

在使用static类型声明方法时需要注意的是,如果在类中声明了一个static类型的属性,则此属性既可以在非static类型的方法中使用,也可以在static类型的方法中使用。但用static类型的属性调用非static类型的属性时,会出现错误。

【例5-28】PersonStatic.java。5.10.3main()方法

在前面的章节中已经介绍,如果一个类要被Java解释器直接装载运行,那么这个类中必须有main()方法。

由于Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public,又因为Java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static的。该方法接收一个String类型的数组参数,该数组中保存执行Java命令时传递给所运行的类的参数。

向Java中传递参数可用如下命令:

java类名称参数1参数2参数3

通过运行下面的程序可了解如何向类中传递参数以及程序又是如何取得这些参数的。

【例5-29】TestMain.java。运行程序:

javaTestMainfirstsecond

输出结果:

first

second

程序说明:

(1)程序第14行判断输入参数的个数是否为两个参数,如果不是,则退出程序。

(2)所有接收的参数都被存放在args[]字符串数组中,用for循环输出全部内容。5.10.4静态代码块

一个类可以使用不包含在任何方法体中的静态代码块,当类被载入时,静态代码块被执行,且只执行一次。静态代码块经常用来进行类属性的初始化。

【例5-30】TestStaticDemo5.java。程序说明:

(1)第1~12行声明一个名为Person的类。

(2)第8~11行声明一个静态代码块,此代码块放在Person类中。

(3)第15~18行在类TestStaticDemo5中也声明一静态代码块。

(4)第22、23行分别产生了两个Person类的匿名对象。

从程序运行结果中可以看出,放在TestStaticDemo5类中的静态代码块首先被调用,这是因为程序首先执行TestStaticDemo5类,所以此程序的静态代码块会首先被执行。程序在22、23行产生了两个匿名对象,Person类中的静态代码块只执行了一次,而且静态代码块优先于静态方法,由此可以发现,静态代码块可以为静态属性初始化。案例2static成员变量和实例变量的区别

【案例描述】

用程序模拟赵庄和李庄两个村庄,这两个村庄共用一口水井。

【代码与注释】 5.11构造方法的私有

方法依实际需要,可分为public与private。同样地,构造方法也有public与private之分。到目前为止,所使用的构造方法均属于public,它可以在程序的任何

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论