java面向对象程序设计第四章.ppt

上传人:小飞机 文档编号:6510314 上传时间:2023-11-07 格式:PPT 页数:50 大小:440.50KB
返回 下载 相关 举报
java面向对象程序设计第四章.ppt_第1页
第1页 / 共50页
java面向对象程序设计第四章.ppt_第2页
第2页 / 共50页
java面向对象程序设计第四章.ppt_第3页
第3页 / 共50页
java面向对象程序设计第四章.ppt_第4页
第4页 / 共50页
java面向对象程序设计第四章.ppt_第5页
第5页 / 共50页
点击查看更多>>
资源描述

《java面向对象程序设计第四章.ppt》由会员分享,可在线阅读,更多相关《java面向对象程序设计第四章.ppt(50页珍藏版)》请在三一办公上搜索。

1、Java 初级,第四章 面向对象(上),什么是抽象 类与对象及其关系 类中定义的属性(域)与方法(操作)对象 构造方法 类成员属性和方法的其它修饰符包(Package),主要内容,什么是抽象,抽象的定义,抽象(abstraction)是从被研究对象中舍弃个别的、非本质的、或与研究主旨无关的次要特征,而抽取与研究有关的共性内容加以考察,形成对研究问题正确的简明扼要的认识。,类与对象及其关系,类与对象及其关系,对象是对客观事物的抽象。类是对对象的抽象,在语言中是一种抽象的数据类型。类的定义在Java中可简述为 class 类名 它们的关系是,对象是类的实例,类是对象的模板。,上图很好地说明了类和对

2、象之间的关系。所有的苏35战斗机都是按照一个图纸设计出来的,其中一个飞机改装后不会对其它飞机造成影响,但如果修改图纸,则会影响到以后生产出来的所有飞机。,类中定义的属性与方法,类中定义的属性(域)与方法(操作),类和对象都有属性和操作,属性是事物静态特征的抽象,操作是事物动态特征的抽象。,class FighterPlane String name;int missileNum;void fire()if(missileNum0)missileNum-=1;System.out.println(“now fire a missile!”);else System.out.println(“No

3、 missile left!”);,类的属性或称为“域”,类的方法,注意:,以类为模板产生对象,实质上就是将类中定义的属性或方法代码拷贝到生成的对象当中。当属性为普通数据类型时,其值就在对象内部当中;而当为引用时,引用的对象在对象的外部。类中定义的属性可以被类中所有的方法所访问。方法中的形式参数和定义的局部变量的作用域仅限于方法,局部变量在使用前必须进行赋值初始化。如果局部变量和类中的属性变量重名,则在方法中对同名变量改变的是局部变量。,局部变量应用举例,class FighterPlane1 String name=su30;int missileNum;void init(String _

4、name)String name=_name;System.out.println(name);System.out.println(this.name);public static void main(String args)FighterPlane1 fp=new FighterPlane1();fp.init(su35);,类中定义的方法的递归调用,用Java打印菲波那契数列的第10项(1,1,2,3,5,)public class TestSeqpublic static int fseq(int n)if(n0)return-1;/进行参数校验 if(n=0|n=1)return 1

5、;else return fseq(n-1)+fseq(n-2);public static void main(String args)System.out.println(fseq(10);输出结果为89,递归问题解读,递归问题:一个较为复杂的问题,可以被分解成为若干相对简单且类同的子问题,如此进行分解直到这样的子问题可以直接求解,这样的问题就是递归问题。递归程序直接或间接的调用自身。当递归的规模很大时很容易造成内存空间不足而出现问题,因此,往往需要将递归转为循环进行求解,对 象,对象的产生,对象图是以类图为模板,对象中的属性和方法是以类中定义的属性和方法为参照而产生的,如下图所示:,对象

6、的产生使用下面的代码:new FighterPlane();根据类模板产生一个对象,并在计算机内存中为之开辟相应空间 对象的声明使用下面的代码:FighterPlane fp;fp相当一个遥控器,但此时它并不能遥控任一FighterPlane对象,需要指明它遥控哪个对象。,对象的引用,要把产生的对象和遥控器相连接,需要下面的代码:fp=new FighterPlane();对象的产生和对象的声明不是一个概念,有声明时可以没有对象,正像有遥控器时可以没有电视机一样。当声明被赋予特定对象后,此时,声明就被另一个概念“引用”所取代,也就是说,此时可以通过引用对对象进行控制了。,对象的内存空间,内存空

7、间分为堆和栈,当在程序中发生函数调用时,为被调函数在栈中分配空间,当函数调用完毕后,栈释放。Application程序中的入口函数main,作为一个特殊的函数,其非静态变量都存放在栈中(静态变量放在堆中),fp也不例外,但产生的对象则放在堆里。如图所示,对象作为参数的特点,普通数据类型作为参数传递是值传递,而对象是引用传递。public class X private static int a=0;public static void main(String args)modify(a);System.out.println(a);public static void modify(int a

8、)a+;本程序的输出为0,因为a+是对形式参数进行自增,而不是对象属性a进行自增。,对象的引用传递举例,class IntClass int value;public class RunIntClass public static void modifyValue(IntClass s,int val)s.value=val;public static void main(String args)IntClass a=new IntClass();modifyValue(a,8);System.out.println(a.value);,在A方法中产生对象,A调用B方法,在B中去赋值,然后在A

9、中去使用,class IntClass int value;public class RunIntClass public static IntClass getInstance()/在方法中产生对象 IntClass s=new IntClass();s.value=8;return s;/引用返回 public static void main(String args)/调用环境中去使用 IntClass a=getInstance();System.out.println(a.value);,在A方法中产生对象,在B方法中去使用。,构造方法,构造方法定义,构造方法是一个与类名相同的类方法

10、。每当使用new关键字创建一个对象,为新建对象开辟了内存空间之后,Java系统将自动调用构造方法初始化这个新建对象。,构造方法举例,class IntClass int value;/定义构造方法并初始化value方法,它无返回类型 public IntClass(int val)value=val;public class RunIntClass public static IntClass getInstance()/调用构造方法,从而省略了s.value代码 IntClass s=new IntClass(8);/s.value=8;return s;public static void

11、 main(String args)IntClass a=getInstance();System.out.println(a.value);,构造方法的特征,构造方法的方法名与类名相同。构造方法是类的方法,不能由编程人员通过对象引用来调用,在创建一个类的对象的同时,系统会自动调用该类的构造方法将新对象进行初始化;不能对构造方法指定类型,它有隐含的返回值,该值由系统内部使用;如果指定了相应的类型,则该方法就不是构造方法,如下面代码 public class A void A()System.out.println(Class A);public static void main(String

12、args)new A();上面的代码中A()前因为有返回类型void,则不是构造方法。,构造方法可以重载;构造方法也可以继承;如果用户在一个自定义类中未定义该类的构造方法,系统将为这个类定义一个缺省的空构造方法。这个空构造方法没有形式参数,也没有任何具体语句,不能完成任何操作。但在创建这个类的新对象时,系统要调用该类的缺省构造方法将新对象属性初始化,这个构造方法前的修饰符将同类前的修饰符保持一致。如果自行定义了构造方法,则系统不再创建这个默认的构造方法。,缺省构造方法举例,class IntClass int value;public class RunIntClass public stat

13、ic IntClass getInstance()IntClass s=new IntClass();/系统调用缺省的IntClass的构造方法 s.value=8;return s;public static void main(String args)IntClass a=getInstance();System.out.println(a.value);,构造方法赋值注意事项,当构造方法中的参数名可能与数据成员名相同,使用代表本类对象的关键字this指出数据成员名。例如:public dogs(String Name,int Weight,int Height)this.Name=Nam

14、e;this.Weight=Weight;this.Height=Height;注意:不要使用下面容易混淆的形式 public dogs(String Name,int Weight,int Height)Name=Name;Weight=Weight;Height=Height;,applet程序如果不写构造方法,则系统自动增加一个缺省的不含参数的构造方法(注意,方法前的修饰符为public),applet实例化由系统完成,系统只能调用这个不含参数的构造方法,因此,如果在applet当中定义了含参数的构造方法,则系统编译不会通过。,finalize方法与垃圾回收,C+中有析构函数的概念,析构

15、函数的作用和构造方法的作用正好相反,它是在对象被释放的时候由系统调用的方法。Java中没有析构函数的概念,但是有类似的方法finalize(它是Object类的方法,而Object类是所有类的父类,因此每个类都有finalize方法)。如果我们在类中重写了finalize方法(进行一些后续处理功能如释放一些资源),则当类的对象被当成垃圾释放掉时,调用这个方法,完成我们设定的特定功能。,对象的释放,对象何时成为垃圾,和成为垃圾后什么时候被释放是两个不同的过程;当对象没有任何引用时,对象才能成为垃圾;当成为垃圾时,系统(虚拟机)还并不主动的释放对象所占内存资源,而是在资源不够的情况下才可能进行释放

16、;为了做到“及时”释放,可调用System.gc()方法或类似的方法Runtime.getRuntime().gc()来“提醒”系统进行一次垃圾释放,但是这只是及时通知系统进行一次释放,而不能确保一定释放,因为进行垃圾回收的系统线程级别很低。,类成员属性和方法的其它修饰符,static,用static修饰符修饰的数据成员是不属于任何一个类的具体对象,而是属于类的静态数据成员。它被保存在类的内存区的公共存储单元中,而不是保存在某个对象的内存区中。因此,一个类的任何对象访问它时,存取到的都是相同的数值访问的方式为通过类名加点操作符来访问,也可通过对象引用来访问。,static数据成员应用例1,im

17、port java.awt.*;import java.applet.*;class Pc static double ad=8;public class RunPc extends Applet public void paint(Graphics g)Pc m=new Pc();Pc m1=new Pc();m.ad=0.1;g.drawString(m1=+m1.ad,20,50);g.drawString(Pc=+Pc.ad,20,70);g.drawString(m=+m.ad,20,90);,static数据成员应用举例2,public class TestStatic exten

18、ds Test private static int i=0;TestStatic()i+;public int getI()return i;public static void main(String args)TestStatic t=new TestStatic();t=new TestStatic();System.out.println(t.getI();,输出结果为2,用static修饰符修饰的方法被称为静态方法,它是属于整个类的类方法,不属于类的任何对象。,Static修饰的方法有如下特点:static方法是类方法,但可以被所有对象所访问,引用这个方法时,可以使用对象名做前缀,

19、也可以使用类名做前缀。static方法内部的代码,只能访问类中的static属性或方法,不能访问类中的非static属性或方法(因为那是对象方法),但非static方法(对象方法)可以访问static数据成员。main方法是特殊的静态方法,是Application程序入口点,必须写成public static void main(String args)的形式。,Main函数参数的应用举例,public class RunIntClass int value;public static void main(String args)for(int i=0;iargs.length;i+)Syst

20、em.out.println(argsi);,运行结果如下:,注意:,不要在main静态方法中直接访问value,因为main是属于类级别的方法,而value属于对象属性。如果main方法中缺少static,则编译能够通过,但是并不能做程序的入口。如下面的代码:public class Foo public void main(String args)(Hello+args0);程序的执行效果为:,静态代码块,一个类中可以使用不包含在任何方法体中的静态代码块,当类被装载时,静态代码块被执行,且只被执行一次,静态代码块经常用来对类中定义的属性进行初始化。class Test static int

21、 value;static value=3;System.out.println(value=+value);public static void main(String args)程序输出结果为3,final,final修饰属性,则属性为常量;如果修饰方法,则方法称为最终方法,在子类当中不能被覆盖(见多态一节),可防止任何继承类修改此方法,保证了程序的安全性和正确性。public Constant static final int OK=0;static final int CANCEL=1;.可以在Constant类中定义一些静态常量,在别的类当中这样来使用:Constant.OK。也可定

22、义对象的属性常量,native修饰的本地方法,修饰符native修饰的方法称为本地方法,此方法使用的目的是为了将其它语言(例如,C、C、FORTRAN、汇编等)嵌入到Java语言中。这样可以充分利用已经存在的其它语言的程序功能模块或是保留其原有的性能指标,避免重复编程。由于native方法嵌入其它语言书写的模块是以非Java字节码的二进制代码形式嵌入Java程序的,而这种二进制代码通常只能运行在编译生成它的平台之上,所以整个Java程序的跨平台性能将受到限制或破坏。此修饰符连同后面要学到的访问控制符(public、protected、private)不能修饰方法内部的变量。,包(Package

23、),包(Package),随着Java的应用,SUN公司的JDK,各系统开发商,以及自己开发的类越来越多,如何对这些类进行有效的组织管理,进而有效使用呢?Java的解决办法是引入包的方式。,默认包举例,class FighterPlane String name;int missileNum;void fire()if(missileNum0)System.out.println(now fire a missile!);missileNum-=1;else System.out.println(No missile left!);,public class RunPlane public s

24、tatic void main(String args)FighterPlane fp=new FighterPlane();fp.name=苏35;fp.missileNum=6;fp.fire();,默认包,以上程序我们在编译时,通常将它们放置在一个文件当中,文件名称为RunPlane.java(类前修饰符必须为public,其它类不能有public),编译后将产生两个class,通过运行java RunPlane得到结果;或是将它们放置在两个java文件,对这两个文件同时编译(javac FighterPlane.java RunPlane.java),编译后得到两个class,通过运行

25、java RunPlane得到结果。这两种情况虽然没有引入包的内容,但它们都是包的一种特殊存在形式默认包。,默认包的缺点,前面的方法只是在进行程序演示的时候使用,在工程上这样做会出现什么问题呢?源文件和字节码文件在一起,当源文件较多时,显然不合适。所以好的方法首先应该将源文件和字节码文件分开。其次,应根据源文件的类型进行分类,将它们的字节码文件按照包的类型进行分类。,打包过程,建立相应的源程序目录 在d:myjava下建立srcresource子目录,将FighterPlane.java存放在此目录当中。将RunPlane.java存放到srcrun目录下。并建立和src并列的deliver,

26、用于存放各包文件。如图所示:,修改FighterPlane.java程序如下,package com.resource;public class FighterPlane public String name;public int missileNum;public void fire()if(missileNum0)System.out.println(now fire a missile!);missileNum-=1;else System.out.println(No missile left!);,对FighterPlane.java进行如下方式编译,进入myjava目录,执行命令行

27、:javac-d.deliver srcresourceFighterPlane.java 其中,-d代表将编译好的字节码文件以当前目录为基准进 行打包。由于在FighterPlane.java程序中有关键语句 package com.resource;则在当前目录下出现了deliver子 目录和resource子子目录。在java体系中把它们看作包名,修改RunPlane.java程序如下,package com.run;import com.resource.*;public class RunPlane public static void main(String args)Fighte

28、rPlane fp=new FighterPlane();fp.name=苏35;fp.missileNum=6;fp.fire();对RunPlane.java进行如下方式编译:进入myjava目录,执行命令行,javac-d.deliver-classpath.deliver srcrunRunPlane.java,执行RunPlane,执行命令行:其中-classpath是命令行开关(可在系统中设置环境变量,这样就不用每次都要输入了开关命令了),表示当前的class应该以此目录为基准去寻找指定的类,在找类的时候,deliver.run.是包的路径,沿着这个路径能找到类RunPlane.c

29、lass(在此,你可否明白为什么java命令后面的class文件不能带后缀的原因吗?)。在执行过程中,RunPlane又要用到FighterPlane,它们不在同一个包中,RunPlane又是怎样找到FighterPlane的呢?关键是import deliver.resource.*;它以classpath所设置的路径为基准,找到了FighterPlane,并且类前的修饰符为public,所以能够引用。,Jar文件,Jar命令格式:Jar cvf first.jar-C deliver 这个命令行的含义是:jar和javac以及java一样都是JDK的工具集。c(create,创建一个新文件);v(生成详细输出到标准输出上);f(指定存档文件名,也就是后面的first.jar);deliver是将其下的所有文件压缩到first.jar当中(可用winRar打开)。对jar文件想知道更多,输入jar得到相应的帮助。-C 的作用是将指定目录下的所有包进行打包。有了first.jar,在执行上就可采用如下方式,假如我们当前在d:下,可以输入下面的命令行执行程序,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号