Java基础第6章类设计

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

1第六章类设计面向对象是一种强力的软件开发方法,它将数据和操作视为一个相互依赖、不可分割的整体。由于面向对象的方法更符合人们的思维习惯,同时有助于控制软件的复杂性、提高效率,从而得到了最广泛的认可,也已经成为目前最为流行的一种软件开发方法。在各个不同版本的中,对面向对象理念的解释也都是大同小异。其中以是Coad、Yourdon的:“面向对象=对象+类+继承+消息通讯”最为著名。也被人们所熟知。6.1类与对象对象的初始化通常由类的构造器来完成。我们可以简单的把构造器理解为一种特殊的成员方法,在每次创建对象时自动被调用。使用构造器要注意以下几个问题:1.构造器必须与类名相同;2.构造器不能添加返回类型;3.构造器只能用范围限定修饰符来修饰;4.构造器一般是公有的;5.构造器通常仅仅进行对象的初始化工作;6.构造器是被系统自动调用的,不能像调用其他普通方法那样显式的调用构造器。下面先看一个circle类的例子例6.1:publicclasstest{publicstaticvoidmain(Stringargs[]){circlec=newcircle();c.output();}}classcircle{doubler;//半径doublepai;//圆周率publiccircle(){r=3.5;pai=3.14;}publicvoidoutput(){System.out.print(圆的面积为:\t);System.out.println(pai*pai*r);}2}当主方法使用new关键字来创建circle对象时,就会自动调用构造器。其实除了可以用构造器进行初始化外,还能通过“语句块”的方式来实现。下面就通过“语句块”的方式来改写circle类,代码如下:例6.2:classcircle{doubler;//半径doublepai;//圆周率{r=3.5;pai=3.14;}publicvoidoutput(){System.out.print(圆的面积为:\t);System.out.println(pai*pai*r);}}这看起来很难理解。然而我们只需要知道JAVA中能支持这种用法就够了。其实普通的“语句块”是很少用到的。用的更多的是static“语句块”来给类中的静态属性初始化。从上面的代码中,我们很容易的发现:很显然把圆周率(pai)定义为静态的更为合理一些。例6.3:classcircle{doubler;//半径staticdoublepai;//圆周率{//普通(非静态)语句块r=3.5;}static//静态语句块{pai=3.14;}publicvoidoutput(){System.out.print(圆的面积为:\t);System.out.println(pai*pai*r);}}3其实JAVA引入“语句块”的概念也是无奈之举:因为众所周知,JAVA是不支持静态构造器的。所以引入“语句块”就是为了解决静态属性初始化的问题。从上面的例子我们能够非常清楚的看出“语句块”就是用一对{}括起来的属性赋值语句,并且本身不能接受任何参数。所以JAVA中的“语句块”跟C#中的静态构造方法比起来就落了下乘。然而有总剩余无,我们所能做的也仅仅是期望在新的JDK版本中能有新的突破。通过上面的例子,我们了解了“语句块”的概念。那么也需要知道构造器、非静态“语句块”、静态“语句块”在类实例化时的调用顺序。大多数的读者,往往并不太关心这种非常细节的技术问题。试想一下在非静态“语句块”中和构造器中都对同一个属性赋了值,那么最终是哪一个值呢?这种细节的东西如果没掌握住,那么在调试程序的时候会浪费大量的时间,并且往往找不到问题的所在。构造器与非静态“语句块”每实例化一个对象就调用一次。而静态“语句块”则是不管实例化多少个对象,都只在实例化第一个对象时才被调用一次。而调用的先后顺序是:静态语句块-非静态语句块—构造器。下面给出一个可以运行的程序,读者可以编译运行它来加深理解。例6.4:publicclasstransferSequence{{System.out.println(**我是非静态的代码块,创建多少个对象我就被调用多少次);}static{System.out.println(--我是静态的代码块,无论创建多少个对象我都被调唯一的调用次);}publictransferSequence(){System.out.println(我是类的构造器);}}classtest_transferSequence{publicstaticvoidmain(Stringargs[]){transferSequencetemp1=newtransferSequence();transferSequencetemp2=newtransferSequence();transferSequencetemp3=newtransferSequence();}}保存为:transferSequence.java4编译:javactransferSequence.java运行:javatest_transferSequence结果:--我是静态的代码块,无论创建多少个对象我都被调唯一的调用次**我是非静态的代码块,创建多少个对象我就被调用多少次我是类的构造器**我是非静态的代码块,创建多少个对象我就被调用多少次我是类的构造器**我是非静态的代码块,创建多少个对象我就被调用多少次我是类的构造器6.2类中的高级应用在类的设计过程中,有几个重要的修饰符号。下面我们依次介绍它们的用法:6.2.1static关键字JAVA中,类声明属性、方法、内部类时,可以使用static关键字作为访问修饰限制符。Static标记的属性或方法有整个类(类的所有实例)共享。如果访问权限允许,我们就可以通过“类名.方法(属性)名”引用。因此静态成员也可以称为类成员。下面的程序将有助于理解:例6.5:publicclassperson{publicstaticinttotal=0;publicperson(){total++;System.out.println(人数为:\t+total);}}classtest_person{publicstaticvoidmain(Stringargs[]){person.total=20;System.out.println(人数为:\t+total);persontemp=newperson();}}需要注意的是:静态方法只能访问当前类中的静态字段。而非静态方法却能直接使用静态字段。此外还要特别注意的是:局部变量是不能声明为静态的。细心的读者可能会发现局部变量不但不能用static来声明,而且连访问修饰限制符都不能用。56.2.2this关键字在谈this关键字之前,还需要先了解一下局部变量的概念以及它的生存周期、优先级。我们通常所说的“局部变量”,在大多数情况下都指的是方法中定义的字段。是跟类体中直接定义的字段相比,才有的“局部变量”的概念。而且两者之间的区别也是很微妙的。先看下面的示例程序:例6.6:1publicclasstest_partVariable2{3publicstaticvoidmain(Stringargs[])4{5partVariabletemp=newpartVariable();6temp.output();7}8}9classpartVariable10{11Stringa;12publicpartVariable()13{14a=“Kevin”;15}16publicvoidoutput()17{18Stringa=“waston”;//局部变量19System.out.println(a);20}21}运行后,发现结果是”waston”(如果是初学者,可能会很困惑)。其实原因很简单,就是局部变量的特性搞的鬼。在揭示这个特性之前,我们还需要知道变量作用域的概念。所谓的作用域,指得就是变量的生存区间(即:所在的那对大括号)。还是以上面的程序为例,第11行的变量a,它的作用域是整个partVariable类.而第14行的a,它的作用域仅仅是output()这个方法。前面所提到的“特性”就是:在变量的生存区间内,作用域范围越小的变量优先级越高。所以在19行输出语句输出的a值就是第18行定义的,值为”waston”。那么怎么才能在output()中输出第11行的变量a呢?这就需要用到this关键字。下面用this关键字改写上面的代码例6.7:1publicclasstest_partVariable2{63publicstaticvoidmain(Stringargs[])4{5partVariabletemp=newpartVariable();6temp.output();7}8}9classpartVariable10{11Stringa;12publicpartVariable()13{14a=“Kevin”;15}16publicvoidoutput()17{18Stringa=“waston”;//局部变量19System.out.println(“将输出18行的值a=”+a);System.out.println(“将输出11行的值a=”+this.a);20}21}this关键字只能在类的方法内部使用,表示对“当前方法所在对象”的引用。所以this的用法和其他普通对象一样。编译下面的示例程序,将会发现另一个问题。例6.8:publicclasstest{publicstaticvoidmain(Stringargs[]){partVariable.print();}}classpartVariable{staticStringstr=********;publicvoidoutput(){Stringstr=&&&&&&&&&;//局部变量System.out.println(this.str);}}通过编译上面的代码会发现,前面提到的“问题”指的是:在静态方法中是不支持this关键字的。这也是很符合定义this关键字的初衷的。因为在前面我们提到了:this是属于7对象的,而静态方法是属于类所有。6.2.3Get、set方法和JavaBean技术虽然JAVA也有所谓的get和set方法,然而它的形式意义远大于它的实际意义。因为get和set方法仅仅是在编程的时候的一种格式约定,就像代码缩进一样,它并不是由语言本身所提供的。众所周知:为了实现类的良好的封装性,(在不考虑继承的前提下)我们往往喜欢把属性定义为private类型,然后再提供一个public方法来获取或更改它。然而对于这样的方法,在方法名前面加上set或get。这是一个良好的习惯,因为这样会让代码变得更加清晰有序。请看下面的程序实例:例6.9:classstudent{privateStringname;//姓名privateStringsex;//性别privateintage;//年龄publicvoidsetName(Stringname){this.name=name;}publicStringgetName(){returnname;}publicvoidsetSex(Stringsex){this.sex=sex;}publicStringgetSex(){returnsex;}publicvoidsetAge(intage){this.age=age;}publicintgetAge(){returnage;}}很多程序员对这种业内“约定”的东西不感兴趣。因为按照业内“约定”做,会给自己增加许多的负担,却往往不能得到立竿见影的好处,所以很多人就慢慢的放弃了。可惜,正是这种“短视”的做法,才使得自己在今后的职业生涯中为此付出了很大的代价。说到了get和set方法就不得不说JavaBean。与get和set方法一样,JavaBean技术称为约定更合适。关于JavaBean是这样定义:在类中只定义私有的属性、

1 / 33
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功