版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java语言简介
1.1 Java语言的发展简介1991年SunMircosystem公司成立了一个Green项目开发小组,JameGosling为组长;设计Java
采用虚拟机代码(VirtualMachineCode),即.class文件,它通过解释器运行;1995年5月SunMircosystem公司对外正式发布Java1.0;Java2用途:适用于各种应用开发,尤其是网络应用,网络服务和嵌入式系统。*Java语言是建立在C++语言之上:1.2 Java语言的特点
一种简单的、面向对象的、分布式的、解释执行的、健壮的、安全的、结构中立的、可移植的、高效的、多线程的、动态的语言*简单性Java与C/C++保持了一定的兼容性,与C++类似,但比C++简单;Java取消了C/C++中很少用的、难以理解的、容易混淆的特性。BillJoy的观点:Java=C++--*面向对象Java以类组织程序,并且硬性规定:所有类的根结点都是Object类,其余的类都是其子类;Java采用面向对象的思想组织程序,支持OO的三个基本特性,即:封装性、多态性和继承性。*分布性Java提供的接口支持HTTP和FTP等TCP/IP协议类库,Java应用程序可以采用URL地址直接访问网络上的对象。*解释执行Java采用先编译后解释执行,顺序如下:1采用编辑器编程并保存;2编译器对.java源文件编译,生成一种称为.class的字节码文件;3
装载器将.class的字节码文件装入内存;4字节码检验器对字节码进行安全检验,若其不违背Java的安全性,将继续进行,否则停止;5
解释器对字节码解释执行。*健壮性Java取消了指针;Java引入了异常(Exception)处理机制。*安全性语言结构设计严谨,对象的方法和变量具有public、protected、private和友元不同的保护机制;取消了指针;字节码文件附带有一些安全检验信息;浏览器在运行.class文件时,也要对其进行安全检验。*结构中立字节码的中介方式,与运行平台无关;与C++相比,Java语言定义严格。例如:classmyclass{//考虑a和b的大小和初值 inta;
intb=1;//其它数据成员和方法略}*可移植性语言定义严格,结构中立;Java提供的类库,不论是对哪一种操作系统都一样;每种基本类型的变量所占的空间大小,在Java中是确定不变的。*高效编译器先将程序编译为与机器指令非常接近的字节码,从而提高了执行效率,但是,与采用编译方式的C/C++相比,还是具有一定差距。*多线程进程在执行中有自己独立的内存空间和资源,各进程的内存数据和状态彼此孤立,交换数据通过特定的通信机制完成;线程在执行中共享内存空间和资源,之间可直接进行数据交换;Java真正支持多线程,C/C++等语言都不支持多线程。*动态性
Java程序的基本构成单元是类,Java程序必须写在类中。并且类是在运行时动态加载的,不影响程序的运行。*1.5Java开发工具J2sdk:http://免费下载;
目前Java的1.4.2版本已经和NetBeans3.5.1捆绑,通过NetBeans这个集成环境可以方面地进行程序的编辑、编译、生成和运行。*VisualJ++6.0/8.0
VJ++还吸收了VB集成开发环境IDE的特征,是一个强有力的Java程序开发工具。1.6 Java程序的分类基于控制台的应用程序;基于浏览器运行的小程序applet。小程序与应用程序的区别是:小程序必须依赖一个HTML文件和支持Java的网络浏览器。注意:采用某种开发工具演示小程序和应用程序,并解释各个语句的含义。**应用程序举例(程序1-1):publicclasshello{publicstaticvoidmain(Stringargs[]){System.out.println("HelloJava!");}}*小程序举例(程序1-2):importjava.awt.Graphics;//注意该行的含义importjava.applet.Applet;
publicclasssayhelloextendsApplet{publicvoidpaint(Graphicsg){g.drawString("HelloJava!",35,30);}}*小程序对应的HTML文件:<HTML><appletcode="sayhello.class"height=100width=200></applet></HTML>Java程序注释方法从C++引入的方法,即//方式;从C/C++中引入的老的注释方法,即/**/,该方法支持多行注释;/***/方式,便于javadoc程序自动生成文档。*1.8 写Java程序的风格要求提高程序可读性的措施:使用有意义的变量名;使用合理的缩进和对齐,程序显得层次分明;使用空行分隔不相关的语句;增加注释语句。例如:
*//程序1-3importjava.awt.Graphics;//Graphics类importjava.applet.Applet;//Applet类
publicclasssayhelloextendsApplet{publicvoidpaint(Graphicsg){ intXPos=40,YPos=40;//定义坐标
g.drawString("HelloJava!",XPos,YPos);}}写程序时的忠告变量命名做到“望名知义”;写程序时同一层的语句要上下对齐,从而使程序显得层次分明;空行虽然可没可无,但对于不同段落的程序要加空行隔开;程序中的注释量应当占整个程序的1/3;培养一种自己的风格。*
控制语句*3.1 分支语句
if-else语句;switch-case语句。*3.1.1if语句
if语句的语法格式同C/C++;条件表达式必须是布尔类型,例如:*下面的写法在C/C++中是合法的,但在Java中却是非法的:inti=10;if(i)...
程序3-1描述了用applet从文本框获取数据,然后将比较的结果显示出来。
//程序3-1importjava.awt.*;importjava.applet.*;publicclasscompareNumbersextendsApplet{ Labellab1,lab2; TextFieldinput1,input2; intnum1,num2; publicvoidinit(){ lab1=newLabel("输入第1个整数"); input1=newTextField(10); lab2=newLabel("输入第2个整数"); input2=newTextField(10);
add(lab1); add(input1); add(lab2); add(input2); } publicbooleanaction(Evente,Objecto){ if(e.target==input1||e.target==input2){ num1=Integer.parseInt(input1.getText()); num2=Integer.parseInt(input2.getText());
if(num1<num2) showStatus(num1+"<"+num2); elseif(num1>num2) showStatus(num1+">"+num2); elseshowStatus(num1+"=="+num2); } returntrue; }}3.1.2 switch语句
switch语句的语法结构同C/C++;switch后面的表达式类型必须是字符类型或整形;case后面的常量不能重复;*3.1.2 switch语句(续)对程序3-2的提示:(char)(Math.random()*26+‘a’)是产生一个‘a’~‘z’之间的随机字符;程序3-3采用小程序实现将学生的百分制成绩转换为优、良,中、及格和不通过五个等级:*//程序3-3importjava.awt.*;importjava.applet.*;
publicclassscoreConvertextendsApplet{ Labelprompt; TextFieldinput; intExcellent,Good,Middle,Pass,Failure; publicvoidinit(){ prompt=newLabel("输入成绩"); input=newTextField(2); add(prompt); add(input); }
publicvoidpaint(Graphicsg){ g.drawString("各等级的人数:",25,40); g.drawString("优秀:"+Excellent,25,55); g.drawString("良好:"+Good,25,70); g.drawString("中等:"+Middle,25,85); g.drawString("及格:"+Pass,25,100); g.drawString("不通过:"+Failure,25,115); } publicbooleanaction(Evente,Objecto){ intscore=Integer.parseInt(o.toString()); showStatus(""); input.setText("");
switch(score/10){ case10: case9:Excellent++;break; case8:Good++;break; case7:Middle++;break; case6:Pass++; break; case5: case4: case3: case2: case1: case0:Failure++; break; default:showStatus(“输入有误,重新输入!"); }
repaint(); returntrue; }}程序3-3需要注意的地方在action()方法中调用的repaint()方法,是一个系统方法,它具有自动调用paint()方法的能力,从而实现对网页的刷新。*3.2 循环控制语句
Java中的循环控制语句有三种,分别是:while,do-while和for语句;循环体内的语句会反复执行,直到控制布尔表达式的值变为false为止。
*3.2.1 while语句
while语句格式:
while(Boolean-Expression)StatementS程序示例3-4略*3.2.2 do-while语句
do-while语句的语法格式如下:do{Statement}while(Boolean-Expression);程序3-5如下:*//产生一个大于0.9的随机数为止publicclassGenerateDoubleNumbers{ publicstaticvoidmain(Stringargs[]){ doubled;
do{ d=Math.random(); System.out.println(d); }while(d<0.9); }}3.2.3
for语句
for语句语法格式如下:
for(ForInitopt;Boolean-Expression;ForUpdateopt)
Statement*//程序3-6输出一个?三角形publicclassprintGraphicsextendsApplet{ publicvoidpaint(Graphicsg){ intxpos,ypos=0;
for(introw=6;row>=1;row--){ xpos=25; ypos+=15;
for(intcolumn=1;column<=row;column++){ g.drawString("*",xpos,ypos); xpos+=7; } } }}3.3 break语句和continue语句
不带标号的break和continue语句;带标号的break和continue语句。
*3.3.1
不带标号的break语句和continue语句
break语句可以跳出包含它的最内层的循环,不再执行剩余的语句;continue语句停止执行当前的循环,回到循环处,开始执行下一轮的循环。这些特性和C/C++的功能一样。
*3.3.2带标号的break语句和continue语句
当在循环中执行带标号的break语句时,可以立即退出任意多个嵌套循环。语法格式:breakIdentifier;当在循环中执行带标号的continue语句时,可以将控制转移到标号的地方,开始下一轮的循环。语法格式:continueIdentifier;程序3-8给出了带标号的break语句用法。*//程序3-8publicclasshello{publicstaticvoidmain(Stringargs[]){inti,j=0;
outer: for(i=0;i<5;i++) for(j=0;j<5;j++){ System.out.println(i+""+j); if(j==1)
breakouter; }
System.out.println("最终值:"+i+""+j);}}程序运行结果:0001最终值:01如果将上述程序中的breakouter修改为continueouter,再次运行该程序,结果如下:000110112021最终值:31这两个带标号语句的共同点都必须用在循环中,用于流程控制;执行这两个语句时,若后面还有其它语句,将不在继续执行。
*这两个带标号语句在用法上的区别
continue语句的标号必须位于封闭的循环语句的前面。如下用法就是错误的:
*outer:{ i=0; for(i=0;i<3;i++) for(j=0;j<3;j++){ System.out.println(i+""+j); if(j==1) continueouter; } }用法区别(续)break语句的标号也必须位于封闭语句的前面,但不一定是循环语句。
例如:*outer:{ i=0; for(i=0;i<3;i++) for(j=0;j<3;j++){ System.out.println(i+""+j); if(j==1) breakouter; } }
Java的类*4.1 类与对象在Java程序中,除原子类型的变量以外都是对象,连Java程序本身也不例外。类是面向对象程序设计的基础,OO始终是围绕着对象的封装性、继承性和多态性展开讨论的。*4.1.1 类与对象的区别类是一个抽象的概念,对象是一个具体的概念。类是在一组对象的基础上,通过抽象和概括获得的一个概念。对象是由数据和方法紧密结合的一个封装体,具有信息隐藏的能力。对象可以通过方法(函数)与其它对象进行通信,但并不知道这些方法的实现细节。*4.1.2 Java和C编程思想的区别C是结构化的编程语言,以函数为编程单元,程序员把注意力集中在编写函数上。Java是面向对象的编程语言,以类为编程单元,程序员的精力集中在对类的设计上。对象将实例变量(instancevariable)和对数据的操作(即方法)约束在一起,类似一个独立的程序,易于扩充,易于维护,代码可复用。*4.1.3 如何定义类类是对象的模板,它定义了对象的结构和操作数据的方法。定义格式如下:*classclassNameextendssuperClassName{typeinstance-vairbale1;return-typemethodName1(parameter-list){method-body;}
}4.1.3 如何定义类(续)系统类Object是整个类层次结构中的根。类内定义的变量称为实例变量,函数称为方法;Java将类的定义和类的实现放在一起,便于系统维护。例如:*4.1.3 如何定义类(续)*classpoint{//Object类的子类
intx,y;
voidinit(inta,intb){
x=a;y=b; }}4.1.4 对象和引用对象是客观存在的变量,对象的引用就是对象的名字,例如:pointp1;创建对象:p1=newpoint();一个对象可以有多个别名;将一个变量设置为null,表明该变量不代表任何对象:p1=null;每个对象都有自己的变量,改变一个对象的实例变量并不影响到另外一个对象。例如:*classpoint{ //程序4-1 intx,y; voidinit(inta,intb){
x=a;y=b;}}
publicclasstwoPoint{publicstaticvoidmain(String[]args){ pointp1=newpoint(),p2=newpoint();
p1.x=10; p1.y=20; p2.x=30; p2.y=40; System.out.println("x="+p1.x+"y="+p1.y); System.out.println("x="+p2.x+"y="+p2.y);}}4.2 方法方法是一个功能模块,类似C中的函数;方法和实例变量都必须定义在类内,方法是类的功能接口;定义方法的原则:方法应当只执行单一的任务,并且方法名能有效地表达该任务;方法的返回值类型、方法名和参数表共同称之为方法的特征。*4.2 方法(续)调用方法的格式:引用.方法名(参数表);
*例如:pointp1=newpoint(),p2=newpoint();p1.init(10,20);//仅对p1对象的x和y进行赋值4.3 实例变量和局部变量Java中的变量分为两种:类内定义的实例变量,方法中定义的局部变量。在同一个作用域内,不允许定义两个同名的局部变量。局部变量可以掩盖实例变量。*classloc{//程序4-2 intx=1; //实例变量
voidprintLocVar(){ intx=25; //局部变量
System.out.println("\nxis:"+x); ++x; System.out.println("xis:"+x); } voidprintInstanceVar(){ System.out.println("\nxis:"+x); x*=10; System.out.println(xis:"+x); }}publicclasstestInstanceVar{ //程序的主类
publicstaticvoidmain(Stringargs[]){ locobj=newloc(); intx=5; //局部变量x
System.out.println("xis:"+x); obj.printLocVar(); obj.printInstanceVar(); System.out.println("xis:"+x); }}4.3 实例变量和局部变量(续)实例变量属于对象,它描述了对象的属性,随着对象的存在而存在;局部变量是随着方法的调用而存在,一旦方法调用结束,局部变量也就消亡了。*4.4 构造函数构造函数的功能是在创建对象时初始化对象的实例变量;构造函数与类具有相同的名字;构造函数没有返回值;如果类中没有定义构造函数,编译器会自动创建一个缺省的、不带参数的构造函数。构造函数是在对象创建之后,new操作完成前被调用的。*classpoint{ //程序4-3 intx,y;
point(inta,intb){
x=a; y=b; }}publicclasscreatePoint{ publicstaticvoidmain(Stringargs[]){ pointp=newpoint(10,20);
System.out.println(p.x+""+p.y); }}思考:无构造函数怎么办?4.5 方法重载方法重载是在一个类中定义二个或多个同名的方法,但方法的参数个数或类型不完全相同;例如:*classpoint{ intx,y;
point(inta,intb){
x=a; y=b; }
point(){
x=-1; y=-1; }}注意以下两点一旦定义了构造函数,Java就不能再调用系统缺省构造函数;方法重载的一个误区是靠返回值区别重载,即定义多个方法,它们的名称和形参类型完全相同,但返回值不同,这是不允许的。*4.6 关键字thisthis指代对象,例如:*classIntVector{ //程序4-6 intv[]; booleanequals(IntVectorother){ if(this==other) returntrue; returnfalse; }}
classtestIntVector{publicstaticvoidmain(Stringargs[]){ IntVectort1=newIntVector(),
t3=newIntVector(),t2=t1;
System.out.println(t1.equals(t2));
System.out.println(t3.equals(t2)); }}4.6 关键字this(续)this指代对象可以用于解决实例变量被局部变量屏蔽的问题。例如:*classpoint{ intx,y;
voidinit(intx,inty){
this.x=x;
this.y=y; }}4.6 关键字this(续)Java中的级连调用,仍是指代当前对象的this。例如:*//程序4-7importjava.awt.*;importjava.applet.*;
classtime{ privateinthour,min,sec;
time(){ setHour(0); setMin(0); setSec(0); }
timesetHour(inth){
hour=((h>=0&&h<24)?h:0); returnthis; }
timesetMin(intm){ min=((m>=0&&m<60)?m:0); returnthis; }
timesetSec(ints){ sec=((s>=0&&s<60)?s:0); returnthis; }
Stringtostring(){ returnhour+":"+min+":"+sec; }}publicclasstimeToStringextendsApplet{
privatetimet;
publicvoidinit(){ t=newtime(); }
publicvoidpaint(Graphicsg){
t.setHour(18).setMin(30).setSec(20);
g.drawString("time:"+t.tostring(),25,45); }}4.6 关键字this(续)在构造函数内部使用this,它用于指代另外一个构造函数,但不能指代非构造函数。例如:*classpoint{ intx,y;
point(){ this(-1,-1); }
point(inta,intb){ x=a; y=b; }}4.7 继承
继承是软件重用的一种形式,可以提高系统的性能;Java不支持多继承,但支持多接口;子类的对象也是其超类的对象,反之未必;继承具有传递性。*继承语法:classclassNameextendssuperClassName{
各实例变量和方法的定义}
classpoint{ intx,y; point(intx,inty){ this.x=x;this.y=y;} point(){this.x=0;this.y=0;}}
classcircleextendspoint{ intradius;
circle(intr,intx,inty){ radius=r; this.x=x;
this.y=y; }}关键字super构造函数是一种特殊的方法,子类不能继承超类的构造函数,但子类构造函数可以通过super调用超类的构造函数。
当创建子类对象时,首先执行超类构造函数,然后执行子类的构造函数。例如:
*classpoint{//程序4-8intx,y;point(intx,inty){
this.x=x; this.y=y; System.out.println("父类构造函数被调用!");}}
classcircleextendspoint{intradius;circle(intr,intx,inty){
super(x,y);
radius=r; System.out.println("子类构造函数被调用!");}}publicclasstestInherence{publicstaticvoidmain(Stringargs[]){ circlec1;
c1=newcircle(1,1,1); }}再次讨论构造函数
若父类没有定义构造函数,那么对父类数据的初始化将采用系统缺省的构造函数;例如:
*classpoint{
intx,y;}
classcircleextendspoint{intradius;circle(intr,intx,inty){ this.x=x;this.y=y;radius=r;}}再次讨论构造函数(续)若父类定义有缺省构造函数,那么子类可根据自己的需要设置自己的构造函数。例如:
*classpoint{ intx,y;
point(){ this(0,0);}
point(intx,inty){this.x=x;this.y=y;}}
classcircleextendspoint{//注意子类的构造函数 intradius; circle(intr,intx,inty){ radius=r;}}再次讨论构造函数(续)若父类定义的构造函数都是有参的,那么子类构造函数必须通过super调用父类构造函数,例如:*classpoint{privateintx,y;
point(intx,inty){this.x=x;this.y=y;}}classcircleextendspoint{intradius;circle(intr,intx,inty){
super(x,y);
radius=r;}}4.8 方法的覆盖
方法的覆盖发生在父类和子类之间,若子类中定义的某个方法的特征,与父类中定义的某个方法的特征完全一样,那么就说子类中的这个方法覆盖了父类对应的那个方法。
*4.8.1 覆盖与重载的区别
重载可以出现在一个类中,也可以出现在父类与子类的继承关系中,并且重载方法的特征一定不完全相同。覆盖特点:子类中的方法特征与父类定义的对应方法的特征完全一样。例如:
*//程序4-9classpoint{ intx,y;
point(){this(0,0);} point(intx,inty){ this.x=x;this.y=y;}
doublearea(){return0;}}classcircleextendspoint{ intradius;
circle(intr,intx,inty){super(x,y);radius=r;}
doublearea(){returnMath.PI*radius*radius;}}publicclasstestOverWrite{publicstaticvoidmain(Stringargs[]){ circlec1;
c1=newcircle(1,1,1); System.out.println(c1.area()); }}4.8.2 方法的动态调用
Java的所有对象运行时都有一个类型标识(RTTI:Run-TimeTypeIdentification),该标识记录了每个对象所属于的类。Java用此标识在运行时选择正确的方法。例如:*//程序4-11classpoint{
intx,y;
point(){this(0,0);} point(intx,inty){this.x=x;this.y=y;}
doublearea(){return0;}}
classcircleextendspoint{
intradius; circle(intr,intx,inty){super(x,y);radius=r;}
doublearea(){//覆盖了父类的area方法
returnMath.PI*radius*radius; }}publicclassdynamicalCall{publicstaticvoidmain(Stringargs[]){ pointp[]={newpoint(2,2),newcircle(1,1,1)};
for(inti=0;i<p.length;i++){ System.out.print(“类名:”+ p[i].getClass().getName()); System.out.print(“父类:”+ p[i].getClass().getsuperclass()); System.out.println(“面积:”+
p[i].area()); } }}方法的动态调用小节子类对象调用方法时(1)子类检查是否具有同名和同参数类型的方法,若有调用该方法,否则继续执行。(2)到父类中寻找同名和同参数类型的方法,若有调用该方法。若找不到,将产生编译错误。 对象决定自己到底该调用哪个方法,取决于该对象在继承链中的位置。
*4.9 多态性不适合继承链中的实例变量
对象.方法:根据多态性调用;对象.实例变量:根据对象的类型调用。即:多态性仅仅适用于方法的调用,而不适合实例变量。例如:*classBase{ //程序4-12
intx=1;
voidprint(){ System.out.println(“当前类为”+
this.getClass().getName()); System.out.println("对象的x="+this.x); }}classDerivedextendsBase{
intx=2;
voidprint(){ System.out.println(“当前类为”+
this.getClass().getName()); System.out.println("对象的x="+this.x); }}publicclassconfusions{ publicstaticvoidmain(String[]args){ Baseobj=newDerived();
obj.print(); System.out.println("对象的x="+obj.x); }}
下面是输出结果:当前类为Derived对象的x=2对象的x=14.10 finalizeJava的垃圾回收器具有自动回收垃圾的能力。垃圾回收器是一个优先级比较低的线程,在系统空闲时运行。
在对象被回收之前,有时需要执行一些特殊的操作,例如保存文件、清除屏幕等,这时就要用Java的finalize方法。例如:
*classpoint{//程序4-13intx,y;
point(inta,intb){ x=a;y=b; System.out.println("pointconstructor:"+getString());}
publicvoidfinalize(){//注意该方法
System.out.println("pointfinalizer:"+getString());}
StringgetString(){ return"x="+x+"y="+y;}}classcircleextendspoint{intradius;
circle(intr,inta,intb){ super(a,b); radius=r; System.out.println("circleconstructor:"+getString());}
publicvoidfinalize(){
System.out.println("circlefinalizer:"+getString());}
StringgetString(){ returnsuper.getString()+"radius="+radius;}}publicclasstestFinalize{publicstaticvoidmain(Stringargs[]){ pointc1,c2; c1=newcircle(1,1,1); c2=newcircle(2,2,2);
c1=null;
c2=null; System.gc();}}程序运行结果:pointconstructor:x=1y=1radius=0circleconstructor:x=1y=1radius=1pointconstructor:x=2y=2radius=0circleconstructor:x=2y=2radius=2circlefinalizer:x=1y=1radius=1circlefinalizer:x=2y=2radius=24.11 staticstatic修饰变量(与C中的不同);static修饰方法(与C中的不同);
*4.11.1 static变量
static变量是指这样的成员变量:不管在程序运行中生成多少个该类的对象,它们都共享该变量。即使没有创建对象,该变量仍然存在。因此,static变量又称为类变量。定义格式为:statictypevariableName;static变量和一般的实例变量不同,在构造函数中不能对它进行初始化。例如:
*classpoint{//程序4-14
staticintcount;
intx,y;
static{ //静态初始化块
count=0; System.out.println("staticvariableisinitialized!"); }
point(inta,intb){ count++;
x=a; y=b; System.out.println("Callpointconstructor!"); }}publicclasstestStaticVariable{publicstaticvoidmain(Stringargs[]){ pointc1=newpoint(0,0);
System.out.println("Thereare"+ point.count+"points"); }}
程序输出结果:staticvariableisinitialized!Callpointconstructor!Thereare1points4.11.2 static方法
static方法是类中的成员方法,它属于整个类,即使不创建任何对象,也可使用静态方法。在子类中不能覆盖父类中定义的静态方法。调用静态方法格式:类名.方法名(参数);静态方法中只能出现静态变量和其它静态方法。并且还不能使用this和super。例如:*classpoint{//程序4-15staticintcount; //定义静态变量intx,y; static{ count=0; System.out.println("staticvariableisinitialized!");}point(inta,intb){ count++;
x=a;y=b; System.out.println("Callpointconstructor!");}
staticintgetCount(){ //静态方法
returncount;}}publicclasstestStaticMethod{publicstaticvoidmain(Stringargs[]){ pointc1=newpoint(0,0); pointc2=newpoint(1,1);
System.out.println("Thereare"+
point.getCount()+"points"); }}4.12 关键字final在实例变量、局部变量和方法的形参定义之前加上final,那么这个变量值只能被引用,而不能修改。final修饰的局部变量和实例变量必须给出初值,因为它修饰的变量代表一个常量。例如:
*classBase{ //程序4-16 finalintx=1; //形式1:修饰实例变量
voidprint(finalinty){ //形式2:修饰参数
//
y=0; //错误
System.out.println(x+y); }}
publicclassfinalVariables{ publicstaticvoidmain(String[]args){ finalintvar=100; //形式3:修饰局部变量
Baseobj=newBase();
obj.print(var); }}4.12.2 final方法
在方法定义前加上final,该方法就不能被子类覆盖,成为终极方法;包含终极方法的类仍然可以被子类继承,子类虽然不能覆盖父类中的终极方法,但可以重载该方法。例如:
*classBase{ finalintx=1;
finalvoidprint(inty){ //父类中的final方法
System.out.println(x+y); }}
classDerivedextendsBase{ voidprint(){ //重载了父类中的print方法
System.out.println(x); }}4.12.3 final类
在一个类定义前加上final,意味着这个类就不能被其它类继承,成为终极类。系统类基本上都是final类,如String类。将class定义为final是为了杜绝继承,类中的方法自然都变成了终极方法。例如:*finalclassBase{ //声明为final类
finalintx=1;
voidprint(finalinty){ System.out.println(x+y); }}
//错误:不能继承final修饰的Base类classDerivedextendsBase{}4.13 组合与继承
面向对象中的软件重用表现为两种形式:继承和对象组合。
设计这类程序的关键是构造函数:子类构造函数调用父类构造、成员对象的初始化。例如:*classdate{ //程序4-17intyear,mon,day; date(inty,intm,intd){ year=y;mon=(m>0&&m<13)?m:1; day=checkday(d);}intcheckday(intd){ intdaydisp[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; if(d>0&&d<=daydisp[mon]) returnd; if(mon==2&&d==29&&(year%400==0|| year%4==0&&year%100!=0)) returnd; return1;} Stringtostring(){returnyear+"/"+mon+"/"+day;}}classemployee{ //雇员类
longid;
datebirthday;
employee(longno,intyear,intmon,intday){ id=no;
//设置组合对象
birthday=newdate(year,mon,day); }
Stringtostring(){ returnid+","+birthday.tostring(); }}classmanagerextendsemployee{ //经理类
doublebasePay;
manager(longno,inty,intm,intd){ super(no,y,m,d); //调用父类构造函数
basePay=1000; }
Stringtostring(){ returnbasePay+","+super.tostring(); }}publicclasscompositionAndInherence{ publicstaticvoidmain(String[]args){ managerboss;
boss=newmanager(1001,1971,11,5); System.out.println(boss.tostring()); }}程序运行结果如下:1000.0,1001,1971/11/54.14 抽象类和抽象方法
抽象方法:仅有方法特征,但没有代码;抽象类:包含抽象方法的类。但是,不包含抽象方法的类也可以是抽象类。抽象类的作用:提供一种适当的超类,子类通过继承实现父类中的抽象方法。
抽象类不能用final修饰。抽象类体现了多态性,通过继承可以从抽象类派生出具有相似操作的子类。例如:**//程序4-18abstractclassinstrument{abstractvoidplay(); //抽象方法 }
//wind不是抽象类classwindextendsinstrument{voidplay(){ System.out.println("windplay!");}}
//percussion也是抽象类classpercussionextendsinstrument{voidplay(){System.out.println("percussionplay!");}}//stringed也不是抽象类classstringedextendsinstrument{ voidplay(){System.out.println("stringedplay!");} }
classwoodWindextendswind{//覆盖父类中的play方法voidplay(){System.out.println("woodWindplay!");}}
classbrassextendswind{//覆盖了父类中的play方法voidplay(){ System.out.println("brassplay!");}}publicclassmusic{ staticvoidtuneAll(instrumente[]){ for(inti=0;i<e.length;i++)e[i].play(); } publicstaticvoidmain(String[]args){ instrumentorchestra[]=newinstrument[5]; inti=0;
orchestra[i++]=newwind(); orchestra[i++]=newpercussion(); orchestra[i++]=newstringed(); orchestra[i++]=newwoodWind(); orchestra[i++]=newbrass(); tuneAll(orchestra); }}程序运行结果:windplay!percussionplay!stringedplay!woodWindplay!brassplay!4.15 对象的类型转换
类型向上转换(upcasting);类型向下转换(downcasting)。
*4.15.1 向上类型转换
从子类向父类转换,在继承图中是向上移动,通常称为向上类型转换。类型向上转换是安全的,因为这是从特殊类型到通用类型的转换。进行向上类型转换时,出现的唯一问题是可能丢失子类中定义的方法和变量。例如:
*//程序4-19classpoint{ intx,y;
point(intx,inty){ this.x=x;this.y=y;} intgetX(){ returnx;}}
classcircleextendspoint{ intradius;
circle(intr,intx,inty){super(x,y); radius=r;} doublearea(){returnMath.PI*radius*radius;}}publicclasstestUpCasting{ publicstaticvoidmain(String[]args){ circlec=newcircle(1,1,1); pointp=c; //注意:p和c的类型不同
System.out.println(p.getX()); }}4.15.2 向下类型转换
从父类向子类转换,在继承图中是向下移动,称为向下类型转换。类型向下转换是不安全的,因为这是从一般类型到特殊类型的转换。例如:*publicstaticvoidmain(String[]args){ pointp=newpoint(1,1); circlec;
if(pinstanceofcircle){//判断能否进行类型转换
c=(circle)p; System.out.println(c.area()); }else //出错处理
System.out.println("cannotdownCasting");}4.16 访问权限限制
Java提供的访问权限修饰符有四个,即public、private、protected和友元;修饰符要置于每个类成员的定义之前,且仅能控制它所修饰的那个成员。*4.16.1 友员缺省修饰符的情况就是友员。友员修饰符意味着同一个目录(包)中的所有类都可以访问这种类型的成员。friendly不属于Java关键字,是C++的一个关键字。例如:*publicclassBase{//该类位于Base.java文件中 intfriend_data=1; //友员数据成员}
//该类位于Derived.java文件中publicclassDerivedextendsBase{ Basep=newBase();
//访问Base类中的friend_data
voiddataUse(){ System.out.println("data="+p.friend_data); }}4.16.2 public成员
不管两个类是否位于同一个目录中,一个类总可以访问另一个类的public成员。
public还可以用于修饰主类,文件名必须与主类名一致。除此之外,其它3个修饰符都不能用于修饰类,只能修饰成员。例如:
*publicclassBase{
publicintfriend_data=1; //public成员}
publicclassDerivedextendsBase{ publicBasep=newBase();
publicvoiddataUse(){ System.out.println("data="+p.friend_data); }}4.16.3 private成员
private成员的特性:除了其所在类能够访问该成员以外,其它类都不能访问它。
在多人合作开发一个系统的过程中,private可以让你自由使用自己定义的成员,无须担心与其他人写的类相冲突。例如:*//程序4-20classBase{
privateBase(){ }//注意
staticBasemakeBase(){returnnewBase(); }}
publicclasstestPrivate{ publicstaticvoidmain(Stringargs[]){
//Basep=newBase();//编译有错
Basep=Base.makeBase(); }}4.16.4 protected成员
protected与继承有关,这种类型的成员可以被子类访问。同一个包内的非子类,也可以访问这种类型的成员。即:protected天生就具有友元权限,例如:*//程序4-21classBase{ //该类位于Base.java文件中
intfriend_data=1; //友元成员publicintpublic_data=2; //public成员privateintprivate_data=3; //private成员protectedintprotected_data=4;//protected成员}
classDerivedextendsBase{ //Derived.java文件 Basea=newBase(); voiddataUse(){ System.out.println(a.friend_data); System.out.println(a.public_data);
//System.out.println(a.private_data);
System.out.println(tected_data); }}//将主类存放在testData.java文件中publicclasstestData{ publicstaticvoidmain(Stringargs[]){ Derivedd=newDerived(); d.dataUse(); }}程序运行结果:124
接口和包*5.1 接口
引入接口的原因:在程序设计中经常遇到这样一个问题:有些类互不相关,但却具有相似的方法。并且这些方法在各个类中的实现互不相同。我们不能为这些类定义一个共同的父类,但又希望在程序中体现出它们共同的接口。
*5.1.1 接口的定义和应用
接口是一系列常量和空方法的集合,它提供了多个类共同的方法,但不限制每个类如何实现这些方法。Java允许一个类同时实现多个接口,相当于实现多继承的功能。
*5.1.1 接口的定义和应用(续)声明一个接口的语法格式:
*[public]interfaceinterfaceName[extendssuper-interface-List]{
typeConstantName=value;
typeMethodName(Parameterlists);}5.1.1 接口的定义和应用(续)接口中不能声明任何变量和构造函数。如果一个类实现多个接口,应该在接口名之间用逗号隔开。
当一个类实现接口时,必须实现接口中给出的空方法,若实现接口的类是一个抽象类,可以把实现接口的任务交给子类去实现。例如:*//程序5-1interfaceSortable{ //定义一个接口intCompare(Sortables);}
classSort{ //定义一个排序类,仅有一个静态的方法publicstaticvoidSelectSort(Sortablea[]){ inti,j,k; Sortabletemp;
for(i=0;i<a.length-1;i++){//选择排序 k=i; for(j=i+1;j<a.length;j++) if(a[k].Compare(a[j])<0) k=j; temp=a[i];a[i]=a[k];a[k]=temp; }}}classStudentimplementsSortable{//定义一个学生类
privateintscore; Student(intx){ score=x; }
//实现接口Sortable中的方法 publicintCompare(Sortables){
Studentst=(Student)s; //类型强制转换
returnscore-st.score; }
publicStringtoString(){return"score="+score;}}classRectangleimplementsSortable{//矩形类也实现了接口
pr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《请同学们注意》课件
- 2026中国5G通信技术应用市场分析及商业机会挖掘研究报告
- 2026脑机接口技术临床应用伦理审查及产业化路径研究
- 《舍得人生大道理》课件
- 《组件装配参考》课件
- 2026中国钟表行业产品研发与市场定位规划
- Reddit彩妆报告:关键主题、趋势、品牌-REDDIT MAKEUP REPORT KEY THEMES,TRENDS,BRANDS
- 《腾讯SNS分析》课件
- 2026年医保知识考试及答案-医保信息化建设应用数据库管理试题
- 2026年理性皮肤测试题及答案
- 中国树莓果汁市场销售格局与未来经营效益盈利性研究报告
- 2026秋人教PEP五年级上册英语全册语法知识点讲义(含专项练习)
- 2026年南宁市青秀区社区工作者招聘笔试备考题库及答案详解
- VDA6.3-2026版 过程审核完整培训教材
- 高中主题班会 珍爱生命远离毒品课件-高中主题班会
- 供应商绩效考核方案实施细则
- 公司法务审批制度
- 比亚迪造车工作制度
- 新时期高校统战工作:问题剖析与创新发展路径探究
- 河北省石家庄市等2地2025-2026学年高二上学期10月月考物理试题
- 《思想道德与法治》课件-2.6辩证对待人生矛盾-曲艺
评论
0/150
提交评论