《java面向对象程序设计第四章.ppt》由会员分享,可在线阅读,更多相关《java面向对象程序设计第四章.ppt(50页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Java 初级初级第四章 面向对象(上)l什么是抽象l类与对象及其关系l类中定义的属性(域)与方法(操作)l对象l构造方法l类成员属性和方法的其它修饰符l包(Package)主要内容主要内容什么是抽象抽象的定义抽象的定义抽象抽象(abstraction)是从被研究对象中舍弃个别的、非本质的、或与研究主旨无关的次要特征,而抽取与研究有关的共性内容加以考察,形成对研究问题正确的简明扼要的认识。动物动物经过人类抽象用一个叫”动物”的类来概括类与对象及其关系类与对象及其关系类与对象及其关系 l对象是对客观事物的抽象。l类是对对象的抽象,在语言中是一种抽象的数据类型。l类的定义在Java中可简述为cla
2、ss类名l它们的关系是,对象是类的实例,类是对象的模板。上图很好地说明了类和对象之间的关系。所有的苏35战斗机都是按照一个图纸设计出来的,其中一个飞机改装后不会对其它飞机造成影响,但如果修改图纸,则会影响到以后生产出来的所有飞机。类中定义的属性与方法类中定义的属性(域)与方法(操作)类中定义的属性(域)与方法(操作)类和对象都有属性和操作,属性是事物静态特征的抽象,操作是事物动态特征的抽象。classFighterPlaneStringname;intmissileNum;voidfire()if(missileNum0)missileNum-=1;System.out.println(“no
3、wfireamissile!”);elseSystem.out.println(“Nomissileleft!”);类的属性或称为“域”类的方法注意:注意:l以类为模板产生对象,实质上就是将类中定义的属性或方法代码拷贝到生成的对象当中。l当属性为普通数据类型时,其值就在对象内部当中;而当为引用时,引用的对象在对象的外部。l类中定义的属性可以被类中所有的方法所访问。l方法中的形式参数和定义的局部变量的作用域仅限于方法,局部变量在使用前必须进行赋值初始化。如果局部变量和类中的属性变量重名,则在方法中对同名变量改变的是局部变量。局部变量应用举例局部变量应用举例classFighterPlane1St
4、ringname=su30;intmissileNum;voidinit(String_name)Stringname=_name;System.out.println(name);System.out.println(this.name);publicstaticvoidmain(Stringargs)FighterPlane1fp=newFighterPlane1();fp.init(su35);类中定义的方法的递归调用类中定义的方法的递归调用用Java打印菲波那契数列的第10项(1,1,2,3,5,)publicclassTestSeqpublicstaticintfseq(intn)i
5、f(n0)return-1;/进行参数校验if(n=0|n=1)return1;elsereturnfseq(n-1)+fseq(n-2);publicstaticvoidmain(Stringargs)System.out.println(fseq(10);输出结果为89递归问题解读递归问题解读 l递归问题:一个较为复杂的问题,可以被分解成为若干相对简单且类同的子问题,如此进行分解直到这样的子问题可以直接求解,这样的问题就是递归问题。l递归程序直接或间接的调用自身。l当递归的规模很大时很容易造成内存空间不足而出现问题,因此,往往需要将递归转为循环进行求解 对象对象的产生对象的产生 对象图是以
6、类图为模板,对象中的属性和方法是以类中定义的属性和方法为参照而产生的,如下图所示:NEW类对象对象的产生使用下面的代码:newFighterPlane();根据类模板产生一个对象,并在计算机内存中为之开辟相应空间对象的声明使用下面的代码:FighterPlanefp;fp相当一个遥控器,但此时它并不能遥控任一FighterPlane对象,需要指明它遥控哪个对象。对象的引用对象的引用l要把产生的对象和遥控器相连接,需要下面的代码:fp=newFighterPlane();l对象的产生和对象的声明不是一个概念,有声明时可以没有对象,正像有遥控器时可以没有电视机一样。l当声明被赋予特定对象后,此时,
7、声明就被另一个概念“引用”所取代,也就是说,此时可以通过引用对对象进行控制了。NEW类对象对象的内存空间对象的内存空间内存空间分为堆和栈,当在程序中发生函数调用时,为被调函数在栈中分配空间,当函数调用完毕后,栈释放。Application程序中的入口函数main,作为一个特殊的函数,其非静态变量都存放在栈中(静态变量放在堆中),fp也不例外,但产生的对象则放在堆里。如图所示栈内存栈内存0 x90000 x9000name堆内存堆内存new FighterPlane()产生的对象产生的对象fp某某函函数数的的栈栈空空间间对象作为参数的特点对象作为参数的特点 普通数据类型作为参数传递是值传递,而对
8、象是引用传递。publicclassXprivatestaticinta=0;publicstaticvoidmain(Stringargs)modify(a);System.out.println(a);publicstaticvoidmodify(inta)a+;本程序的输出为0,因为a+是对形式参数进行自增,而不是对象属性a进行自增。对象的引用传递举例对象的引用传递举例classIntClassintvalue;publicclassRunIntClasspublicstaticvoidmodifyValue(IntClasss,intval)s.value=val;publicstat
9、icvoidmain(Stringargs)IntClassa=newIntClass();modifyValue(a,8);System.out.println(a.value);在A方法中产生对象,A调用B方法,在B中去赋值,然后在A中去使用sa对象classIntClassintvalue;publicclassRunIntClasspublicstaticIntClassgetInstance()/在方法中产生对象IntClasss=newIntClass();s.value=8;returns;/引用返回publicstaticvoidmain(Stringargs)/调用环境中去使
10、用IntClassa=getInstance();System.out.println(a.value);在A方法中产生对象,在B方法中去使用。对象as构造方法构造方法定义构造方法定义 构造方法是一个与类名相同的类方法。每当使用new关键字创建一个对象,为新建对象开辟了内存空间之后,Java系统将自动调用构造方法初始化这个新建对象。构造方法举例构造方法举例classIntClassintvalue;/定义构造方法并初始化value方法,它无返回类型 public IntClass(int val)value=val;publicclassRunIntClasspublicstaticIntCl
11、assgetInstance()/调用构造方法,从而省略了s.value代码 IntClass s=new IntClass(8);/s.value=8;returns;publicstaticvoidmain(Stringargs)IntClassa=getInstance();System.out.println(a.value);构造方法的特征构造方法的特征 构造方法的方法名与类名相同。构造方法是类的方法,不能由编程人员通过对象引用来调用,在创建一个类的对象的同时,系统会自动调用该类的构造方法将新对象进行初始化;不能对构造方法指定类型,它有隐含的返回值,该值由系统内部使用;如果指定了相应
12、的类型,则该方法就不是构造方法,如下面代码 publicclassAvoidA()System.out.println(ClassA);publicstaticvoidmain(Stringargs)newA();上面的代码中A()前因为有返回类型void,则不是构造方法。构造方法可以重载;构造方法也可以继承;如果用户在一个自定义类中未定义该类的构造方法,系统将为这个类定义一个缺省的空构造方法。这个空构造方法没有形式参数,也没有任何具体语句,不能完成任何操作。但在创建这个类的新对象时,系统要调用该类的缺省构造方法将新对象属性初始化,这个构造方法前的修饰符将同类前的修饰符保持一致。如果自行定义了
13、构造方法,则系统不再创建这个默认的构造方法。缺省构造方法举例缺省构造方法举例classIntClassintvalue;publicclassRunIntClasspublicstaticIntClassgetInstance()IntClasss=newIntClass();/系统调用缺省的IntClass的构造方法s.value=8;returns;publicstaticvoidmain(Stringargs)IntClassa=getInstance();System.out.println(a.value);构造方法赋值注意事项构造方法赋值注意事项 当构造方法中的参数名可能与数据成员
14、名相同,使用代表本类对象的关键字this指出数据成员名。例如:publicdogs(StringName,intWeight,intHeight)this.Name=Name;this.Weight=Weight;this.Height=Height;注意:不要使用下面容易混淆的形式publicdogs(StringName,intWeight,intHeight)Name=Name;Weight=Weight;Height=Height;applet程序如果不写构造方法,则系统自动增加一个缺省的不含参数的构造方法(注意,方法前的修饰符为public),applet实例化由系统完成,系统只能调
15、用这个不含参数的构造方法,因此,如果在applet当中定义了含参数的构造方法,则系统编译不会通过。finalize方法与垃圾回收方法与垃圾回收 lC+中有析构函数的概念,析构函数的作用和构造方法的作用正好相反,它是在对象被释放的时候由系统调用的方法。lJava中没有析构函数的概念,但是有类似的方法finalize(它是Object类的方法,而Object类是所有类的父类,因此每个类都有finalize方法)。l如果我们在类中重写了finalize方法(进行一些后续处理功能如释放一些资源),则当类的对象被当成垃圾释放掉时,调用这个方法,完成我们设定的特定功能。对象的释放对象的释放l对象何时成为垃
16、圾,和成为垃圾后什么时候被释放是两个不同的过程;l当对象没有任何引用时,对象才能成为垃圾;l当成为垃圾时,系统(虚拟机)还并不主动的释放对象所占内存资源,而是在资源不够的情况下才可能进行释放;l为了做到“及时”释放,可调用System.gc()方法或类似的方法Runtime.getRuntime().gc()来“提醒”系统进行一次垃圾释放,但是这只是及时通知系统进行一次释放,而不能确保一定释放,因为进行垃圾回收的系统线程级别很低。类成员属性和方法的其它修饰符static 用static修饰符修饰的数据成员是不属于任何一个类的具体对象,而是属于类的静态数据成员。它被保存在类的内存区的公共存储单元
17、中,而不是保存在某个对象的内存区中。因此,一个类的任何对象访问它时,存取到的都是相同的数值访问的方式为通过类名加点操作符来访问,也可通过对象引用来访问。static数据成员应用例数据成员应用例1 1importjava.awt.*;importjava.applet.*;classPcstaticdoublead=8;publicclassRunPcextendsAppletpublicvoidpaint(Graphicsg)Pcm=newPc();Pcm1=newPc();m.ad=0.1;g.drawString(m1=+m1.ad,20,50);g.drawString(Pc=+Pc.a
18、d,20,70);g.drawString(m=+m.ad,20,90);static数据成员应用举例数据成员应用举例2 2publicclassTestStaticextendsTestprivatestaticinti=0;TestStatic()i+;publicintgetI()returni;publicstaticvoidmain(Stringargs)TestStatict=newTestStatic();t=newTestStatic();System.out.println(t.getI();输出结果为2用static修饰符修饰的方法被称为静态方法,它是属于整个类的类方法,不
19、属于类的任何对象。Static修饰的方法有如下特点:static方法是类方法,但可以被所有对象所访问,引用这个方法时,可以使用对象名做前缀,也可以使用类名做前缀。static方法内部的代码,只能访问类中的static属性或方法,不能访问类中的非static属性或方法(因为那是对象方法),但非static方法(对象方法)可以访问static数据成员。main方法是特殊的静态方法,是Application程序入口点,必须写成publicstaticvoidmain(Stringargs)的形式。Main函数参数的应用举例函数参数的应用举例publicclassRunIntClassintvalue
20、;publicstaticvoidmain(Stringargs)for(inti=0;i0)System.out.println(nowfireamissile!);missileNum-=1;elseSystem.out.println(Nomissileleft!);publicclassRunPlanepublicstaticvoidmain(Stringargs)FighterPlanefp=newFighterPlane();fp.name=苏35;fp.missileNum=6;fp.fire();默认包默认包以上程序我们在编译时,通常将它们放置在一个文件当中,文件名称为RunP
21、lane.java(类前修饰符必须为public,其它类不能有public),编译后将产生两个class,通过运行java RunPlane得到结果;或是将它们放置在两个java文件,对这两个文件同时编译(javac FighterPlane.java RunPlane.java),编译后得到两个class,通过运行java RunPlane得到结果。这两种情况虽然没有引入包的内容,但它们都是包的一种特殊存在形式默认包。默认包的缺点默认包的缺点前面的方法只是在进行程序演示的时候使用,在工程上这样做会出现什么问题呢?源文件和字节码文件在一起,当源文件较多时,显然不合适。所以好的方法首先应该将源文
22、件和字节码文件分开。其次,应根据源文件的类型进行分类,将它们的字节码文件按照包的类型进行分类。打包过程打包过程建立相应的源程序目录 在d:myjava下建立srcresource子目录,将FighterPlane.java存放在此目录当中。将RunPlane.java存放到srcrun目录下。并建立和src并列的deliver,用于存放各包文件。如图所示:修改FighterPlane.java程序如下package com.resource;publicclassFighterPlanepublicStringname;publicintmissileNum;publicvoidfire()i
23、f(missileNum0)System.out.println(nowfireamissile!);missileNum-=1;elseSystem.out.println(Nomissileleft!);对FighterPlane.java进行如下方式编译 进入myjava目录,执行命令行:javac-d.deliversrcresourceFighterPlane.java 其中,-d代表将编译好的字节码文件以当前目录为基准进 行打包。由于在FighterPlane.java程序中有关键语句 package com.resource;则在当前目录下出现了deliver子 目录和resou
24、rce子子目录。在java体系中把它们看作包名修改RunPlane.java程序如下package com.run;import com.resource.*;publicclassRunPlanepublicstaticvoidmain(Stringargs)FighterPlanefp=newFighterPlane();fp.name=苏35;fp.missileNum=6;fp.fire();对RunPlane.java进行如下方式编译:进入myjava目录,执行命令行,javac-d.deliver-classpath.deliversrcrunRunPlane.java执行RunP
25、lane执行命令行:其中-classpath是命令行开关(可在系统中设置环境变量,这样就不用每次都要输入了开关命令了),表示当前的class应该以此目录为基准去寻找指定的类,在找类的时候,deliver.run.是包的路径,沿着这个路径能找到类RunPlane.class(在此,你可否明白为什么java命令后面的class文件不能带后缀的原因吗?)。在执行过程中,RunPlane又要用到FighterPlane,它们不在同一个包中,RunPlane又是怎样找到FighterPlane的呢?关键是importdeliver.resource.*;它以classpath所设置的路径为基准,找到了F
26、ighterPlane,并且类前的修饰符为public,所以能够引用。Jar文件文件Jar命令格式:Jarcvffirst.jar-Cdeliver这个命令行的含义是:jar和javac以及java一样都是JDK的工具集。c(create,创建一个新文件);v(生成详细输出到标准输出上);f(指定存档文件名,也就是后面的first.jar);deliver是将其下的所有文件压缩到first.jar当中(可用winRar打开)。对jar文件想知道更多,输入jar得到相应的帮助。-C 的作用是将指定目录下的所有包进行打包。有了first.jar,在执行上就可采用如下方式,假如我们当前在d:下,可以输入下面的命令行执行程序