[计算机软件及应用]Jaa.doc

上传人:音乐台 文档编号:1991558 上传时间:2019-01-28 格式:DOC 页数:65 大小:143KB
返回 下载 相关 举报
[计算机软件及应用]Jaa.doc_第1页
第1页 / 共65页
[计算机软件及应用]Jaa.doc_第2页
第2页 / 共65页
[计算机软件及应用]Jaa.doc_第3页
第3页 / 共65页
亲,该文档总共65页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《[计算机软件及应用]Jaa.doc》由会员分享,可在线阅读,更多相关《[计算机软件及应用]Jaa.doc(65页珍藏版)》请在三一文库上搜索。

1、*补充1:IDE工具:(Integrated Development Environment)集成开发环境,可以辅助开发程序的应用软件,就是你用来编程的软件。C的话,比如VC+,Java的话,比如Eclipse*补充2:我们知道,接口相当于一个抽象类,它不能创建实例,但可以使用“子类的对象也是父类的对象”原理,用接口做为函数的参数类型,这可以实现动态联编(binding).比如某个类A实现了接口I,那么只在是在以I为类型定义的函数参数,把类A创建的对象都可以填进去,如void f(I i) ; *OOP语言有一个性质:子类的对象也是父类的对象,即在任何父类的对象可以应用的地方,子类对象同样可以

2、应用,这是因为子类继承父类,那么它就有父类所有的东西,而且还有可能再发展自己,所以父类有的(比如一些变量,函数等),子类一定有。*Java和C+在定义数据和数据的初始化时有不同点,如:String s;这句话在C+中就是说创建一个String类对象s,但在Java中就是说创建了一个将要指向String类对象的一个引用名,这个引用名叫作s,还要对它进行指派相应的对象。所以,Java中的变量名都是引用名,这点切记!在C+中可以在类内的任何成员函数之前对变量进行定义,但只能在构造函数中对变量进行初始化(这点我深受感触),但在Java中可以在类内的函数之前进行对象的创建和直接初始化。*对System.

3、out.println()函数的注意:如果在这个函数中首次出现字符,那么在之后加到其中的其它数据(如int,float,double)也会以字符型打印。但如果首欠加到其中的是数据类型(如int,float,double)那么会进行数学运算,直到遇到一个字符对象才以字符型打印,如:int x=0,y=1,z=2;String s=”xyz”;System.out.println(s+x+y+z); /打印出:xyz012System.out.println(y+z+s);/打印出3xyz*Java的对象生成和释放:在Java中对象有构造函数,但没有析构函数,比如:String s=new Str

4、ing(“xyz”);这句话会完成三个动作:一个内容为xyz的String类对象被创建了,一个String类的引用名s被创建了,这个引用名s指向了这个xyz对象。在Java中没有析构函数,对象的释放由一个Java内部的垃圾收回机制,这个机制只会在内存快用完后才会进行内存清理,它有自己的一套确定哪些对象是垃圾的算法,一般认为一个对象没有哪个引用名引用它时,基本上可以确定它是一个垃圾了,这时该机制会调用这个对象的finalize()函数进行内存释放,我们知道,在Java中所以的类默认都是继承Object类的,而Object类中定义了finalize()函数,所以每个对象都有finalize()函数

5、。*Java程序的运行机制:Java程序没有传统的程序的思想,它就是类的集合,经编译完成后生成的是*.class文件,即字节码文件,更确切的说是类的描述文件,在Java中,认为一切事物都是对象,要运行程序时,JVM会创建一个对象的空间,并会在这些*.class文件中找到一个类中的main()函数,并从这个函数执行,当这个函数要用到其它类时,JVM才会动态的装载这个类的定义,所以Java程序又是动态的。*初始化顺序:在Java中的类中被创建时,要在内存中建立一块空间,紧接着就是对类内部的定义的对象呀,变量呀什么的进行初始化,然后才是建立构造函数和其它的一些函数,即要时刻记住,在Java的类被创建

6、时,是先建立类内定义的对象,然后才建立成员函数*初始化顺序:我们知道,在Java中所有的东西都可看作是对象,就连动态装载的类的描述文件*.class文件都看作是对象,而且我们还知道用static修辞的变量为对象的公有,不为哪个类所特有,那么这个公共的成员变量放在哪呢,要记住,它就放在*.class文件中,即如果在装载类时发现类内有静态成员的定义,那么就要在类内生成它。下面举例说明:public class StaticInitialization public static void main(String args) System.out.println(Creating new Cupbo

7、ard() int main); . Static Table t1=new Table();class Table Table() .当我们在命令行中键入java StaticInitilization时,发生了什么呢,首先JVM被启动了,然后它要在内存中找StaticInitilization类的类定义,发现没有,那么它要装载这个类的定义文件,于是在内存中就有了StaticInitilization的类描述文件,即StaticInitilization.class文件,这个文件是一个类对象,StaticInitilization.class就代表StaticInitilization这个类

8、(因为在Java中认为一切东西都是对象),而在这个类中发现有静态的Table类的对象t1,就要动态装载Table类的描述文件,在内存中生成Table.class文件,然后再用这个Table类对象来创建t1对象,完成上面的后,再转回执行StaticInitilization类的构造函数所以对上面的总结有:假如类型为Dog的一个对象首次创建时,或者Dog类的静态方法/数据首次访问时,Java解释器必须找到Dog.class,找到Dog.class后,它的所有的静态初始化模块都会运行。因此,静态初始化仅仅发生一次。创建一个new Dog()时,new语句首先会在堆里分配一个足够的空间,这个空间将会被

9、清除为零,因此Dog中所有的数据成员都得到了缺少值。然后定义初始化,最后执行构造函数。因此初始化的顺序为:整个类装载进来,先静态初始化,然后再动态初始化,先定义初始化,后构造函数。分析以下代码:class Cupsstatic Cup cup1;static Cup cup2;static cup1=new Cup(1); cup2=new Cup(2); Cups() 在上面的代码中出现了下面的语句:static cup1=new Cup(1); cup2=new Cup(2); 它在Java中叫静态初始化块,在静态初始化时,这条语句会被执行,它相当于一条静态初始化语句。还有下面语句:cla

10、ss Mugs Mug c1; Mug c2- c1=new Mug(); c2=new Mug(); System.out.println(“c1 & c2 has been created”); Mugs() 上面程序中的部分代码如下,叫定义初始化块,它是在构造函数之前就已经被创建了。如果在Java中有一个没有名字的类,那下面的程序是不是就像是这个没有名字的类的构造函数呢,实际在Java中就有这样的类,而下在的代码也正是这个目的。 c1=new Mug(); c2=new Mug(); System.out.println(“c1 & c2 has been created”); *数据:

11、我们知道在Java中数据有两种定义:int a; int a,个人建议用前者,因为如果用后者,反而会影响你对这个变量a的意义的理解,因为在Java中,数组就是实际上是一个指向数组的句柄(或引用,或指针),int a;说明a是一个数组的引用,它将来要引用一个数组。所以在Java中为数组的方括号中千万不能写上数字,不能写int 5 a;你这样是想说a将来指向一个有5个数据的数组,但这明显有语法错误,不能这么写。分析下面代码:class Arrays int a1=1,2,3,4,5; int a2; Arrays() show(a1); for(int i=0;ia1.length;i+) a1i

12、+; show(a1); a2=a1; show(a2); void show(int b) for(int i=0;i编辑,打开后,在里面写入classpath=再保存就可以了。对classpath的理解,我们知道如果一个类要声明自己属于哪个包,那么它必须在这个以这个包名为文件夹的目录下面,但是在这个包名前还可能有多得目录呢,那么在运行程序时, 怎么能快速找到这个类的定义文件呢,这就要用到classpath,在这个classpath里列出了好多路径,那么JVM就会首先按照这些给定的目录去找这个类的定义。一个小细节,如果在操作台上发现classpath为一个点,那这个点是什么意思,记住,这个点

13、是指当前目录,就是在当前目录下找文件。还有一点要注意,我们在DOS中用javac编译一个*.java文件,是以文件名+.java列出的这个文件,但如果在类文件里声明自己属于哪一个包时,那么编译这个文件时,我们要到这个文件所在的目录下面,键入javac+filename.java进行编译,完了之后,要执行它呀,如果classpath已经设置好了,那么在任何目录下都可以执行它,只不过它的名字不再是文件名了,应改为“包名”+点+“类名“,即这个文件有”姓“了,它姓包名,这时可以在任何盘盘任何目录下执行java命令都可以运行它。但如果没有在类的首行写上包名,那么执行它时不要加上包名。比如在Hellow

14、world.java文件里第一行写了package bag1;那么编译Helloworld.java文件时就要键入:javac bag1.Helloworld.java;*对批处理文件的认识:批处理文件是可以在DOS窗口中以批处理文件名为命令来执行的,就像*.exe文件一样,如java.exe,那么可以在DOS中键入java,再加点参数就可运行了,所以设置环境变量时,也可以写一个脚本文件,里面写上一行一行的命令,然后再运行这个脚本文件,且看我用批处理文件来设置环境变量classpath:打开一个文本编辑器,写上 set classpath=D:,然后保存为batfile.bat,再用DOS把目

15、录行定位符定位到这个文件所在的位置,再键入batfile就OK了,可以再键入set classpath查看是否设置好了。*类成员的访问属性:针对类内的每个成员的每个定义,Java访问属性public,protected和private都必须放在它们的前面无论是数据成员还是方法,这是因为它不能像C+那样,如果public int a,b,c,d,;那么在一个public后面定义的变量太长,在确定变量之前的修辞字时会很困难,所以在Java中规定在每个变量之前都要加关键字,如:public int a;public int b;public int c;*缺省包:在Java中,如果同一个目录下面的所

16、有java程序文件都没有声明自己属于哪个包,那么这些文件同属于一个缺省包,即在这个目录下面的这些文件*类的访问控制:类的访问控制有public,friendly(缺省值),private,protected,其各自的访问权限可见书,比如friendly访问权限是包内可见,什么意思呢,即这个类的定义是在同一个包内可以访问的,又是什么意思呢,即如果这个类的文件在这个包里,那么就可用这个类来创建对象,因为它是包内可见的。现在考虑一个问题,在包内有一个friendly的类,调用这个类的某个函数,它的返回值是类型就是该类的对象,这个返回的对像拿到包外可不可以用,这个你考虑一下,其实它是可以用的。有以下代

17、码:class Soup private Soup() public static Soup makeSoup() return Soup(); 可以看到该类的构造函数是私有的,即其它类的所有函数都不可以访问,在该类中有一个makeSoup()函数,它是静态的,而且必须是静态的,因为如果不是静态的,那要通过该类的对象去调用,而由于该类的构造方法是私有的,不能创建对象,所以无法能过对象调用。在这个makeSoup()函数中,它的返回值是一个Soup类的对象,这也就是上面讲到的问题,可以用包里的类创建对象对外返回。*在Java中子类继承父类的原理:其实在创建子类对象时,首先要在堆里面分配一块内存,

18、然后先调用父类的构造函数,生成一个父类对象,然后再调用子类的构造函数,再创建子类与父类相比多出的东西,这样一来,就创建好了子类对象,所以可以认为子类对象里“内含”父类对象。这里说明一个为什么不先初始化自己,再初始化父亲,因为如果你先初始化自己,在初始化过程中,有可能要用到父亲对象中的变量,而父亲对象还未创建,所以这样不行.*分析有继承的初始化和类的装载:分析以下代码:class Insect 1) int i=9; int j;2) Insect() prt(i=+i+,j=+j); j=39; 3) static int x1=prt(static Insect.x1 initialized

19、); static int prt(String s) System.out.println(s); return 47; public class Beetle extends Insect 4) int k=prt(Beetle.k initialized);5) Beetle() prt(k=+k); prt(j=+j); 6) static int x2=prt(static Beetle.x2 initialized); public static void main(String args) prt(Beetle constructor); Beetle b=new Beetle(

20、); 这里定义了一个Insect类,Beetle类extends Insect,而在Beetle类内部有一个main函数,所以程序从这里执行,在这个main()函数里创建一个Beetle类对象,于是JVM要装载Beetle类,它又发现这个Beetle类是有父亲的,即Insect类,于是又要装载Insect类,在这个Insect类中有一个静态变量x1,所以最先执行的是创建变量x1,即语句3,完了以后再创建子类Beetle类的静态变量x2,即语句6,完成上面的工作后,Insect类和Beetle类都已经装载进来了,现在要用这两个创建对象,先创建父类对象,创建父类对象时,要先定义初始化,再构造函数,

21、于是语句1被执行,接着执行语句2,这样父类对象创建完成;创建子类对象时,也是的,先定义初始化,再构造函数,于是语句4,5分别被执行。通过这个例子,我们也可以看出,在Java的类中,要从哪个类执行就把哪个类设为public的,且在里面要添加main函数,这都不是重点,重点是可以在一个类的内部设置public static void main(String args),可以在这个函数中创建以这个类为类型的对象,上面的代码做到了,即在Beetle类内部创建一个Beetle对象b,而且上面的程序编译后没有问题。当然也可以重新写一个公共类,设置这个类内部只有一个main函数,专门用来使所有的类跑起来的。

22、*Upcasting:在Java中,我们可以把子类对象看作是父类对象的一种(即学生是人,皮鞋是鞋子),这样说是能说通的,那么,听好喽,把子类对象当作父类对象来使用就叫作Upcasting,在我理解它就是动态联编技术,请看下例:import java.util.*;class Instrument protected void play() System.out.println(Instrument Constructor); static void tune (Instrument i)i.play();class Wind extends Instrument protected void

23、play() System.out.println(Wind Constructor); public static void main(String agrs) Wind flute=new Wind();Instrument.tune(flute);类Instrument中有个静态函数tune(Instrument i),在类Wind中的main函数中创建一个Wind对象,它是Instrument类的子类,所以调用i.play()时就用到了上面的所谓Upcasting技术,即动态联编。另外还要说的是Upcasting是安全的,因为把子对象当作父对象,实际是把子对象的能力缩小了,因为父类有的

24、,子类一定有,所以说Upcasting是安全的。*Binding(翻译成中文就是绑定):在Java中,绑定有早绑定和晚绑定之分,早绑定是在编译时就确定绑定结果的,这种绑定运行效率高,但灵活性差,相对于早绑定,晚绑定就是在运行时才绑定的,它灵活性高,但是运行效率不高,在C+中默认是是早绑定,但在Java中默认的是晚绑定。*final:我们知道final可以修辞变量,函数和类。当final修辞变量时,它的值不能被改变,即在运行时只能赋一次值,但这个值什么时候被赋给这个变量是任意的,不一定非要在程序开头赋给它,这点要理解,这是final修辞变量时,当final修辞对象时,我们知道,对象名其实就是引用

25、名,如final Circle c=new Circle(),这时引用名c指向一个Circle对象,那么这时final的含义是引用名c指向这个Circle对象的事实是不能改变的,但这个Circle对象的内部的东西是可以改变的,不能变的仅仅是引用名引用这个对象的事实,这点切记!当用final修辞函数时,即类中的方法,可以认为是对该方法上加一把锁,防止子类改写它的原来含义,即然它的含义不可能被子类改写,那么编译器就会像C+的内部实现一样,把对该方法的调用变成inline调用,即把代码嵌入在类中。另外,我们知道,用private修辞的方法也是不能被子类调用的,所以实现机制和用final修辞的方法是一

26、样的,所以private is final.或private=final最后说说用final修辞类,即final类,这个类可以说是断子绝孙的类,这样的类其实是为了一些安全起见,如果其它的类继承它,并把这个子类放在其它的地方,那就有可能改变原类的行为。现在考虑两个问题,在final类里的成员变量和成员函数是什么属性的?要记住,final类的所有方法都是final的,因为该类不存在子类,所以就不存在方法的重写问题;但final类的成员变量没有这个规定,成员变量是可以改变它的值的。*抽象类:在某些情况下,一个类不想让它有具体的对象,而要用这个类做一个范指,用它的子类生成对象,比如Shape类,由它可

27、以派生出Circle,Rectangular那么可以把这个Shape类定义为一个抽象类。在Java中,我们知道,如果子类继承了抽象的父类,那么它要重写(或实现)父类中的所有抽象函数(当然,父类中不一定所有的函数都抽象的),如果没有一一实现这些函数,那么这个子类还是抽象类。在Java中也允许一个抽象类中的所有函数都有实现,那这个类的目的就是防止产生该类的对象(因为抽象类无法创建对象)。其实在Java中,把这个抽象类的概念又向前推进了一步,即接口(interface)*接口(Interface):接口,即totally abstract class,完全抽象的类,接口的内容不在缀述,但要记住,接口

28、只能继承接口,接口不能继承任何类。另外,关于接口,这里有一个细节:interface Product static final String MAKER=My Corp;static final String PHONE=7963628;public int getPrice(int id);class Shoe implements Product public int getPrice(int id) if(id=1)return 5;else return 10;public String getMaker() return MAKER;public class Store static

29、 Shoe hightop;public static void init() hightop=new Shoe();public static void main(String args) init();getInfo(hightop);orderInfo(hightop);public static void getInfo(Shoe item) System.out.println(This Product is made by +item.getMaker();System.out.println(It cost $ +item.getPrice(1);public static vo

30、id orderInfo(Product item) System.out.println(To order from +item.MAKER);System.out.println(Each item costs $+item.getPrice(1);上述程序定义了一个Product接口,一个Shose类继承了Product接口,一个Store类,在这个Store类中的public static void orderInfo(Product item)方法中的参数为接口Product类的对象,有没有搞错,上面不是说了吗,接口实质就是抽象类,它怎么能创建对象呢?这是一个知识点,Product

31、item说明的是凡是哪个对象实现了这个Product接口,它就可以被当作参数传进来,orderInfo(hightop);中,这个hightop对象实现了Product类,所以可被当作参数传进来,另外要说的是,一个类可以实现多个接口,那么在被当作函数参数时,这个类可以被用在多重情况下,如class A implements I1,I2,.那么类A的对象a可在函数参数为(I1 obj) (I2 obj)等成员函数中被使用!还有,就是上面的程序中有两个类,一个接口,那么编译完成后生成几个.class文件?注意,是三个而不是两个,也即:接口在编译过程中也会生成 接口.class的文件。!*Inner

32、 Class:在Java中往往要用一个对象去访问一个类内部的私有成员,这是内部类产生的原因.在C+中解决这个问题,有一个友元机制,还记得吗,在C+中也有内部类的机制,但比起Java,它差的很多,Java在内部类方面做的很全面。分析下面代码:public class Parcel1 class Contents private int i=11;public int value() return i; class Destination private String label;Destination(String whereTo) label=whereTO;String readLabel

33、() return label; public void ship (String dest) Contents c=new Contents();Destination d=new Destination(dest);我们看到,在这个类Parcel1中,定义了两个内部类Contents和Destination。在Java中,内部类你就把它当作成员类,因为它有类的成员变量和成员函数该有的属性,比如内部类的对象可以访问类内private成员,当然内部类的成员函数也可以访问private成员;内部类也可以在类前加修辞词public,private,比如当用private修辞时,这个内部类创建的对象

34、就像private成员一样,不能被类外的函数访问,等等;当用static修辞内部类是,说明这个内部类属于这个外面的大类.可以看出,它的性质与类的成员变量和成员函数的属性极其相似。现在对上面的类Parcel1进行编译,它会产生几个.class文件呢?上机试,发现,这个Parcel.java会生成3个*.class文件,分别是:Parcel1.classParcel1$Contents.classParcel1$Destination.class可以看到,内部类的命名规则在是外部类后面加上“$”,再加上内部类的类名,关于这里为什么是$呢,因为在有些系统在规定文件名中的点”.”只能出现一次,所以Ja

35、va中用$来取代这个点了。回顾一下用DOS的一方法:列出当前目录中所有文件名的首字母为P,且后缀名为class的文件可以用:dir P*.class*private inner class 内部类可以完全被封装起来,但还有点细节要注意:abstract class Contents abstract public int value();interface Destination String readLabel();public class Parcel3 private class PContents extends Contents / label1;private int i=11;p

36、ublic int value () return i ; protected class PDestination implements Destination private String label;private PDestination(String whereTo) label=whereTo;public String readLabel() return label; public Destination dest (String s) return new PDestination(s);public Contents cont() /label2return new PCo

37、ntents();class Test public static void main(String args) Parcel3 p=new Parcel3();Contents c=p.cont();Destination d=p.dest(Tanzania);/Parcel3.PContents c=new p.Contents();在label1处可以看到在Parcel3类中定义一个私有的内部类PContents,这个类是外部看不到的,再看看label2处的函数cont(),它的返回值是Contents型的,但函数里面返回的却是内部类类型PContents的,在Test类的main()函

38、数中语句Contents c=p.cont();是调用对象p的cont()函数,但实际这个对象c不是Contents型的,而是它的子类,然而我们知道,子类的对象就是父类的对象,这里是可以的,但也能看出另外一个问题,因为PContents是私有的内部类,这个内部类虽然不可被外界访问,但可通过它传出一个它的对象,这是可以的,在上面也谈到这个问题。这也就启发了我们,可以在类内部写私有的内部类,在完成外部要求的任务的同时给要传出的对象多加东西而不被发现 在上面程序的最后一行代码Parcel3.PContents c=new p.Contents();看起来有点怪,但它是本身是正确的,你看,Parcel.PContents代表Parcel类的成员类PContents,即要创建一个PContents类的对象,然后调用Parcel3类的对象中的Content()方法作为构造方法,但在这个程序中是错误的,原因仅在于类Parcel3中的内部类PContents是私有的,如果不是私有的,那这句是一点问题也没有的。一般程序中不会这么写,但这样写是没有错的。下面总结在什么情况下要用到内部类:1. 我们准备实现某种形式的interface,使自己能创建和返回一个句柄(不太懂.)2. 要解决一个复杂的问题,并希望创建一个类,用来辅助自己的程序,同时不愿意把类的细节公开(什么意思

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

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1