工学JAVA学习笔记_第1页
工学JAVA学习笔记_第2页
工学JAVA学习笔记_第3页
免费预览已结束,剩余16页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、"this" 的用法 构造器和方法使用关键字 this 有很大的区别。方法引用 this 指向正在执行方法的类的实例。 静态方法不能使用 this 关键字, 因为静态方法不属于类的实例 ,所以 this 也就没有什么东西 去指向。 构造器的 this 指向同一个类中, 不同参数列表的另外一个构造器, 我们看看下面的 代码:public class Platypus String name;Platypus(String input) name = input;Platypus() this("John/Mary Doe");public static v

2、oid main(String args) Platypus p1 = new Platypus("digger");Platypus p2 = new Platypus();在上面的代码中,有 2 个不同参数列表的构造器。第一个构造器,给类的成员 name 赋值, 第二个构造器,调用第一个构造器,给成员变量name 一个初始值 "John/Mary Doe".在构造器中,如果要使用关键字this,那么,必须放在第一行,如果不这样,将导致一个编译错误。"super"的用法构造器和方法,都用关键字super指向超类,但是用的方法不一样。

3、方法用这个关键字去执行被重载的超类中的方法。看下面的例子:class Mammal void getBirthInfo() System.out.println("born alive.");class Platypus extends Mammal void getBirthInfo() System.out.println("hatch from eggs");System.out.print("a mammal normally is ");super.getBirthInfo(); 在上面的例子中,使用 super.getBi

4、rthInfo() 去调用超类 Mammal 中被重载的方法。构造器使用super去调用超类中的构造器。而且这行代码必须放在第一行,否则编译将出错。 看下面的例子:public class SuperClassDemo SuperClassDemo() class Child extends SuperClassDemo Child() super();在上面这个没有什么实际意义的例子中,构造器Child()包含了 super,它的作用就是将超类中的构造器 SuperClassDemo 实例化,并加到 Child 类中。编译器自动加入代码 编译器自动加入代码到构造器, 对于这个, java 程

5、序员新手可能比较混淆。 当我们写一个没 有构造器的类,编译的时候,编译器会自动加上一个不带参数的构造器,例如:public classExample 编译后将如下代码:public class Example Example() 在构造器的第一行,没有使用super,那么编译器也会自动加上,例如:public class TestConstructors TestConstructors() 编译器会加上代码,如下:public class TestConstructors TestConstructors() super; 仔细想一下,就知道下面的代码public class Example

6、 经过会被编译器加代码形如:public class Example Example() super; 继承 构造器是不能被继承的。子类可以继承超类的任何方法。看看下面的代码: public class Example public void sayHi system.out.println("Hi");Example() public class SubClass extends Example this指向同一个类中另外一个构造器,在第一行 指向当前类的一个实例,不能用于静态方法super 调用父类的构造器,在第一行 调用父类中一个重载的方法继承 构造器不能被继承 方法

7、可以被继承编译器自动加入一个缺省的构造器 自动加入(如果没有) 不支持编译器自动加入一个缺省的调用到超类的构造器 自动加入(如果没有)+JA VA 技 术 专 题 综 述 之 构 造 方 法 篇 +类的继承机制使得子类可以使用父类的功能(即代码) ,并且子类也具有父类的类型。下面 介绍类在继承关系上的初始化的顺序问题。示例 1: class SuperClassSuperClass()System.out.println("SuperClass constructor");public class SubClass extends SuperClassSubClass()S

8、ystem.out.println("SubClass constructor");public static void main(String args)SubClass sub = new SubClass(); 输出结果: SuperClass constructorSubClass constructor 在子类中只实例化了一个子类对象。 从输出结果上看, 程序并不是一开始就运行自己的 构造方法, 而是先运行其父类的默认构造方法。 注意:程序自动调用其父类的默认构造方法。示例 2:class SuperClassSuperClass(String str)Syste

9、m.out.pri ntln ("Super with a stri ng."); public class SubClass exte nds SuperClass SubClass(Stri ng str)System.out.pri ntln ("Sub with a stri ng.");public static void main(String args)SubClass sub = new SubClass("sub"); 在JDK下编译此程序不能成功。正如上例中说的:程序在初始化子类时先要寻找其父 类的默认构造方法,结

10、果没找到,那么编译自然不能通过。解决这个问题有两个办法:1 在父类中增加一个默认构造方法。2 在子类的构造方法中增加一条语句:super(str);且必须在第一句。这两种方法都能使此程序通过编译,但就本程序来说运行结果却不相同。第1种方法的运行结果是:Sub with a stri ng.第2种方法的运行结果是:Super with a stri ng. Sub with a stri ng.第2种解决方法实际上是指定编译器不要寻找父类的默认构造方法,而是去寻找带一个字符串为参数的构造方法。下面介绍对象的初始化顺序问题。示例3:class OneOn e(Stri ng str)System.

11、out.pri ntln( str);class TwoOne one_1 = new On e("o ne-1");One one_2 = new On e(" on e-2");One one_3 = new On e("o ne-3");Two(Stri ng str) System.out.pri ntln( str); public class Test public static void main(String args) System.out.println("Test main() start."

12、);Two two = new Two("two"); 输出结果: Test main() start.one-1 one-2 one-3 two在 main() 方法中实例化了一个 Two 类的对象。但程序在初始化 Two 类的对象时,并非 先调用 Two 类的构造方法, 而是先初始化 Two 类的成员变量。 这里 Two 类有 3 个成员变量, 它们都是One类的对象,所以要先调用3次One类的相应的构造方法。最后在初始化Two类 的对象。示例 4: class One One(String str) System.out.println(str); class Two

13、 One one_1 = new One("one-1");One one_2 = new One("one-2"); static One one_3 = new One("one-3");Two(String str) System.out.println(str); public class Test public static void main(String args) System.out.println("Test main() start.");Two two_1 = new Two("t

14、wo-1");System.out.println("");Two two_2 = new Two("two-2"); 输出结果:Test main() start.one-3one-1one-2two-1 one-1one-2two-2非静态如果一个类中有静态对象, 那么它会在非静态对象前初始化, 但只初始化一次。 对象每次调用时都要初始化。示例 5:class One One(String str) System.out.println(str);class TwoOne one_1 = new One("one-1")

15、;One one_2 = new One("one-2");static One one_3 = new One("one-3");Two(String str) System.out.println(str);3public class Teststatic Two two_3 = new Two("two-3");public static void main(String args) System.out.println("Test main() start.");Two two_1 = new Two(&q

16、uot;two-1");System.out.println("");Two two_2 = new Two("two-2");输出结果:one-3one-1one-2two-3Test main() start.one-1one-2two-1 one-1one-2 two-2程序中主类的静态变量会在main()方法执行前初始化。结果中只输出了一次on e-3,这也说明:如果一个类中有静态对象, 那么它会在非静态对象前初始化, 但只初始化一次。非 静态对象每次调用时都要初始化。示例 6: class One One(String str) Sy

17、stem.out.println(str); class Two static int i = 0;One one_1 = new One("one-1");static One one_2 = new One("one-2");static One one_3 = new One("one-3");Two(String str) System.out.println(str); public class Test public static void main(String args)System.out.println("

18、;Test main() start."); System.out.println("Two.i = " + Two.i);4 输出结果: Test main() start.one-2one-3Two.i = 0不仅第 1 次创建对象时, 类中所有的静态变量要初始化, 第 1 次访问类中的静态变量 (没 有创建对象)时,该类中所有的静态变量也要按照它们在类中排列的顺序初始化。综上所述:在创建对象时, 对象所在类的所有数据成员会首先进行初始化, 如果其中的成员变量有 对象, 那么它们也会按照顺序执行初始化工作。 在所有类成员初始化完成后, 才调用对象所 在类的构造

19、方法创建对象。构造方法作用就是初始化。静态对象(变量)在非静态对象前初始化。静态对象(变量)只初始化一次,再次调用 就不初始化了,但非静态对象在每次调用时都要初始化。程序中的主类的静态变量会在 main() 方法执行前进行初始化工作。不仅第 1 次创建对象时, 类中所有的静态变量要初始化, 第 1 次访问类中的静态变量 (没 有创建对象)时,该类中所有的静态变量也要按照它们在类中排列的顺序初始化。初始化的顺序包括构造方法调用的顺序如下: 1主类的静态成员首先初始化。 2主类的超类的构造方法按照从最高到最低的顺序被调用。3主类的非静态对象(变量)初始化。 4调用主类的构造方法。在一个构造方法中只

20、能调用一次其它的构造方法, 并且调用构造方法的语句必须是第一条语 句。+ 深入剖析 java 类的构造方式 + 概要:本文通过查看一个精心构造的类结构的运行输出和使用 javap 工具查看实际生成的 java字节码(bytecode)向java程序员展示了一个类在运行时是如何构造生成的。关键字: java 构造 javap 字节码 bytecode按照 java 规范,一个类实例的构造过程是遵循以下顺序的:1如果构造方法(con structor,也有翻译为构造器和构造函数的)是有参数的则进行参 数绑定。2内存分配将非静态成员赋予初始值(原始类型的成员的值为规定值,例如int型为0,float

21、型为O.Of, boolean型为false;对象类型的初始值为null),静态成员是属于类对象而非类实例, 所以类实例的生成不进行静态成员的构造或者初始化, 后面将讲述静态成员的生成 时间。3如果构造方法中存在this()调用(可以是其它带参数的this()调用)则执行之,执行完毕后进入第 6 步继续执行,如果没有 this 调用则进行下一步。4执行显式的super()调用(可以是其它带参数的super()调用)或者隐式的super()调用(缺省构造方法) ,此步骤又进入一个父类的构造过程并一直上推至 Object 对象的构造。5执行类申明中的成员赋值和初始化块。6执行构造方法中的其它语句。

22、现在来看看精心构造的一个实例:class Parentint pm1;int pm2=10;int pm3=pmethod(); System.out.println("Parent's instance initialize block"); public static int spm1=10; staticSystem.out.println("Parent's static initialize block"); Parent()System.out.println("Parent's default constr

23、uctor");static void staticmethod()System.out.println("Parent's staticmethod");int pmethod()System.out.println("Parent's method"); return 3;class Child extends Parentint cm1;int cm2=10;int cm3=cmethod();Other co;public static int scm1=10; System.out.println("Chil

24、d's instance initialize block"); staticSystem.out.println("Child's static initialize block"); Child() co=new Other();System.out.println("Child's default constructor");Child(int m) this();cm1=m;System.out.println("Child's self-define constructor"); s

25、tatic void staticmethod()System.out.println("Child's staticmethod");int cmethod()System.out.println("Child's method"); return 3;class Otherint om1;Other() System.out.println("Other's default constructor"); public class InitializationTestpublic static void ma

26、in(String args)Child c;System.out.println("program start"); System.out.println(Child.scm1);c= new Child(10);System.out.println("program end"); 进入此文件所在的目录,然后 编译此文件: javac InitializationTest.java 运行此程序: java ?classpath . InitializationTest 得到的结果是:program startParent's static in

27、itialize blockChild's static initialize block10Parent's methodParent's instance initialize blockParent's default constructorChild's methodChild's instance initialize blockOther's default constructorChild's default constructorChild's self-define constructorprogram

28、end如果没有看过上面的关于类的构造的说明, 很容易让人误解为类的构造顺序是如下的结 果(忽略参数绑定、内存分配和非静态成员的缺省值赋值) :1. 完成父类的非静态成员初始化赋值以及执行初始化块(这个的先后顺序取决于源文件中的书写顺序, 可以将初始化块置于成员声明前, 那么先执行的将是初始化块, 将上面的代 码稍稍变动一下就可以验证这一点。 )2. 调用父类的构造方法完成父类构造。3. 完成非静态成员的初始化赋值以及执行初始化块。4. 调用构造方法完成对象的构造,执行构造方法体中的其它内容。 如果根据以上 java 规范中给出的顺序也可以合理的解释程序的输出结果,那么如何亲 眼看到是规范中的顺

29、序而不是以上根据程序的输出推断的顺序呢?下面就使用 JDK 自带的 javap 工具看看实际的顺序, 这个工具是一个根据编译后的字节 码生成一份字节码的助记符格式的文档的工具,就像根据机器码生成汇编代码那样。反编译: javap -c -classpath . Child 输出的结果是(已经经过标记,交替使用黑体和斜体表示要讲解的每一块) :Compiled from InitializationTest.javaclass Child extends Parent int cm1;int cm2;int cm3;Other co;public static int scm1;static ;

30、Child();Child(int);int cmethod();static void staticmethod();Method static 0 bipush 102 putstatic #22 <Field int scm1>5 getstatic #20 <Field java.io.PrintStream out>8 ldc #5 <String "Child's static initialize block">10 invokevirtual #21 <Method void println(java.lan

31、g.String)>13 returnMethod Child()0 aload_01 invokespecial #14 <Method Parent()>4 aload_05 bipush 107 putfield #16 <Field int cm2>10 aload_011 aload_012 invokevirtual #18 <Method int cmethod()>15 putfield #17 <Field int cm3>18 getstatic #20 <Field java.io.PrintStream out

32、>21 ldc #2 <String "Child's instance initialize block">23 invokevirtual #21 <Method void println(java.lang.String)>26 aload_027 new #8 <Class Other>30 dup31 invokespecial #13 <Method Other()>34 putfield #19 <Field Other co>37 getstatic #20 <Field jav

33、a.io.PrintStream out>40 ldc #1 <String "Child's default constructor">42 invokevirtual #21 <Method void println(java.lang.String)>45 returnMethod Child(int)0 aload_01 invokespecial #12 <Method Child()>4 aload_05 iload_16 putfield #15 <Field int cm1>9 getstatic

34、 #20 <Field java.io.PrintStream out>12 ldc #4 <String "Child's self-define constructor">14 invokevirtual #21 <Method void println(java.lang.String)>17 returnMethod int cmethod()0 getstatic #20 <Field java.io.PrintStream out>3 ldc #3 <String "Child's

35、method">5 invokevirtual #21 <Method void println(java.lang.String)>8 iconst_39 ireturnMethod void staticmethod()0 getstatic #20 <Field java.io.PrintStream out>3 ldc #6 <String "Child's staticmethod">5 invokevirtual #21 <Method void println(java.lang.String)

36、>在开始说明前先解释一下输这个我们在此可以不管, 第二8 return 请仔细浏览一下这个输出并和源代码比较一下。 下面解释如何根据这个输出得到类实例的实际的构造顺序, 出的语句的格式, 语句中最前面的一个数字是指令的偏移值, 项是指令助记符,可以从字面上大致看出指令的意思。例如 getstatic 指令将一个静态成员压入一个称为操作数堆栈(后续的指令就可以引用 这个数据结构中的成员)的数据结构,而 invokevirtual 指令是调用 java 虚拟机方法,第三 项是操作数 (#号后面跟一个数字,实际上是类的成员的标记),有些指令没有这一项,因为有些指令如同汇编指令中的某些指令一样是

37、不需要操作数的 (可能是操作数是隐含的或者根 本就不需要) ,这是 java 中的一个特色。如果你直接检查字节码,你会看到成员信息没有直接嵌入指令而是像所有由 java 类使 用的常量那样存储在一个共享池中, 将成员信息存储在一个常量池中可以减小字节码指令的 大小,因为指令只需要存储常量池中的一个索引而不是整个常量。需要说明的是常量池中的项目的顺序是和编译器相关的, 因此在你的环境中看到的可能 和我上面给出的输出不完全一样, 第四项是对前面的操作数的说明, 实际的字节码中也是没 有的,根据这个你能很清楚的得到实际上使用的是哪个成员或者调用的是哪个方法, 这也是 javap 为我们提供的便利。说

38、完上面这些你现在应该很容易看懂上面的结果和下面将要叙述的内容了。其它更进一步的有关 java 字节码的信息请自己查找资料。先看看最开始的部分,很像一个标准的C+类的声明,确实如此。成员声明的后面没有了成员初始化赋值语句和初始化块,那么这些语句何时执行的呢?先不要急,继续往下看。第二块,是一个 Method statiC ,对比看看第一部分,它被处理为一个静态的方法(从 前面的 Method 可以看出),这就是源代码中的静态初始化块,从后面的语句可以看出它执 行的就是 System.out.println("Child's statiC initialize bloCk&quo

39、t;) 语句, 由于这个方法是没有方法名 的,所以它不能被显式的调用,它在何处调用后面会有叙述。第三块,缺省构造方法的实现, 这是本文的重点,下面详细讲解。 由于源代码中的缺省 构造方法没有显式调用 this 方法,因此没有 this 调用(对比看看下一块的有参的构造方法 的前两句),同时也没有显式的 super 调用,那么隐式调用父类的缺省构造方法,也就是前 两条语句 (主要是语句 invokespeCial #14 <Method Parent()> ),它调用父类的构造方法, 和这 个类的构造相似(你可以使用javap ?c ?classpath . Pare nt反编译父类

40、的字节码看看这个类的构造过程);紧接着的是执行源代码中的第一条初始化赋值语句cm2=10 (即接下来的三条语句,主要是 bipush 10和 putfield #15 <Field int cm2> ,此处回答了第一块中的疑问,即初始 化赋值语句到哪儿去了。 );接下来是执行 cm3=cmethod() (接下来的四条语句) ;然后是执 行初始化块中的内容 System.out.println("Child's instance initialize block") (接下来的三条语 句); java 规范内部约定的内容至此执行完毕,开始执行构造方法的方

41、法体中的内容,即co=new Other()(接下来的五条语句)和System.out.println("Child's default constructor")(接下来的三条语句) ,最后方法执行完毕返回(最后一条语句 return)。剩下的几块相信应该不用解释了吧, 有参构造方法调用无参构造方法然后执行自己的方 法体,成员方法 cmethod 执行一条打印语句然后返回一个常量3,静态方法 staticmethod 执行一条打印语句。另外需要说明一下的是你可以将有参构造方法中的 this 调用去掉, 然后看看反编译的结 果,你会发现两个构造方法非常的类似, 如果

42、你将两个构造方法的内容改为一样的, 那么反 编译后的生成也将是同样的。 从这个可以说明本文开始的构造顺序的说明中构造方法中this调用的判断是在编译阶段就完成的, 而不是在运行阶段 (说明中的意思好像是这个判断是在 运行时进行的) 。对构造过程的另一个细节你可能还不相信, 就是顺序中的第二条关于非静态成员的赋予 缺省初始值(内存分配部分无法考证,这是 java 虚拟机自动完成的) ,这个你可以通过在子 类 Child 的 cmethod 方法的最开始用 System.out.println(cm3) 打印 cm3 的值(输出为 0,其它 类型成员的值可以通过类似的方法得到)下面来讲解另一个还没

43、有解决的问题: 静态成员初始化和静态初始化块的执行是在何时 完成的?这个可以通过一个小小的试验推断得到: 是在第一次使用该类对象时进行的 (注意 是类对象而不是类实例, 对于类的公有静态成员可以直接通过类名进行访问, 并不需要生成 一个类实例, 这就是一次类对象的使用而非类实例的使用, 如果在生成第一个类实例前没有 使用过该类对象, 那么在构造第一个类实例前先完成类对象的构造 (即完成静态成员初始化 以及执行静态初始化块) ,然后再执行以上类实例的构造过程) ,试验的步骤如下:1. 修改 main 方法,将其中的 System.out.println(Child.scm1) 和 c= new

44、Child(10) 都注释掉 (不要删除,后面还需要用到这两个语句) ,编译运行程序,输出将只有 program start 和 program end ,这说明没有使用类对象也没有生成类实例时不进行静态成员的构造。2. 将 System.out.println(Child.scm1) 的注释取消,编译运行后输出多了父类和子类的静态 初始化块部分的执行输出(使用子类的类对象将导致生成父类的类对象,父类先于子类构 造)。3. 将 System.out.println(Child.scm1) 注释掉并取消 c= new Child(10) 的注释,编译运行后输 出只比最开始没有注释任何语句时少了一

45、条(输出 Child.scm1 的值 10)从以上的试验中我们可以得到前面的结论。本文至此可以说结束了,由于本人的 java 功底并不很扎实, java 规范看得也不完整, 因此文中可能有错误,如果您觉得某些地方有错误的话,欢迎通过 mail 联系。 +Java 构造函数运行解析 + 源代码如下 : import java.util.*;class super1System.out.println("super1 ok");super1()System.out.println("3");class Employee extends super1priva

46、te String name;private double salary=1500.00;private Date birthday;public Employee(String n,Date DoB)System.out.println("2");name=n;birthday=DoB;public Employee(String n)this(n,null);System.out.println("4");class Manager extends EmployeeSystem.out.println("Manager ok");

47、private String department;public Manager(String n,String d)super(n); department=d;public class Test1public static void main(String args)new Manager("Smith","sales");程序运行结果:super1 ok324Manager ok 生成成功(总时间: 1 秒) new Manager("Smith","sales") 调用过程 :(1) 绑定构造函数参数。其实

48、就是传递参数的过程(2) 查看是否有this()语句。没有。虽然没有使用this()语句调用构造函数,但是该步骤不能省略调用super()语句,此时,程序跳转到Public Employee(String n)。(4)绑定构造函数参数 String n查看是否有this()。有,则执行构造函数public Employee(String n,Date DoB)(6)绑定构造函数参数 String n,Date DoB查看是否有this()语句。没有(8) 执行有系统自动插入的super()语句:执行super1()(9) 执行显式初始化语句System.out.println("su

49、per1 ok");(10) 执行构造函数语句System.out.println("3");(11) 执行显式初始化语句private double salary=1500.00;(12) 执行构造函数语句System.out.println("2"); 同时执行 name=n;birthday=DoB;(13) 执行构造函数语句 System.out.println("4");(14) 执行显式初始化语句System.out.println("Manager ok");(15) 执行构造函数语句 de

50、partment=d;几点总结:(1) 对象是由 new 运算符创建的,且在任何构造函数执行之前就已经创建完毕了 (2)构造函数的执行总是“向上”的:而且总是先执行完父类的构造函数在构造函数中,没有this()语句则由super()语句。没有this()时,或者自己编写super(),或者由系统自动调用 super()(4)显式初始化语句总是先于构造函数语句,但后于super()或this()+java 构造函数的执行过程 + 类初始化时构造函数调用顺序:( 1)初始化对象的存储空间为零或null 值;(2) 调用父类构造函数;(3) 按顺序分别调用类成员变量和实例成员变量的初始化表达式;(4

51、) 调用本身构造函数。例子:public class Dollar extends MoneyRmb r=new Rmb();public Dollar()System.out.println("Dollar is construct!");public static void main(String args)new Dollar();class Moneypublic Money()System.out.println("Money is construct");class Rmbpublic Rmb()System.out.println(&quo

52、t;RMB is construct");输出结果 :Money is constructRMB is constructDollar is construct!+ 深度理解 JAVA 本身的构造器及子父类构造方法的初始化顺序 + 我们说构造器是一种方法,就象讲澳大利亚的鸭嘴兽是一种哺育动物。(按:老外喜欢打比喻,我也就照着翻译) 。要理解鸭嘴兽,那么先必须理解它和其他哺育动物的区别。同样地,要理解构造器,那么就要了解构造器和方法的区别。所有学习java 的人,尤其是对那些要 认证考试的,理解构造器是非常重要的。下面将简单介绍一下 ,最后用一个表作了些简单 的总结。功能和作用的不同

53、构造器是为了创建一个类的实例。这个过程也可以在创建一个对象的时候用到: Platypus p1 = new Platypus();相反,方法的作用是为了执行 java 代码。 修饰符,返回值和命名的不同 构造器和方法在下面三个方便的区别:修饰符,返回值,命名。和方法一样,构造器可以有 任何访问的修饰: public, protected, private 或者没有修饰 (通常被 package 和 friendly 调用). 不同于方法的是,构造器不能有以下非访问性质的修饰: abstract, final, native, static, 或者 synchronized 。返回类型也是非常重

54、要的。方法能返回任何类型的值或者无返回值( void ),构造器没有返 回值,也不需要 void 。最后,谈谈两者的命名。构造器使用和类相同的名字,而方法则不同。按照习惯,方法通常 用小写字母开始, 而构造器通常用大写字母开始。 构造器通常是一个名词, 因为它和类名相 同;而方法通常更接近动词,因为它说明一个操作。"this" 的用法构造器和方法使用关键字 this 有很大的区别。方法引用 this 指向正在执行方法的类的实例。 静态方法不能使用 this 关键字, 因为静态方法不属于类的实例, 所以 this 也就没有什么东西 去指向。 构造器的 this 指向同一个类中

55、, 不同参数列表的另外一个构造器, 我们看看下面的 代码:public class Platypus String name; Platypus(String input) name = input; Platypus() this("John/Mary Doe"); public static void main(String args) Platypus p1 = new Platypus("digger"); Platypus p2 = new Platypus(); 在上面的代码中,有 2 个不同参数列表的构造器。第一个构造器,给类的成员 nam

56、e 赋值, 第二个构造器,调用第一个构造器,给成员变量name 一个初始值 "John/Mary Doe".在构造器中,如果要使用关键字this,那么,必须放在第一行,如果不这样,将导致一个编译错误。"super"的用法构造器和方法,都用关键字super指向超类,但是用的方法不一样。方法用这个关键字去执行被重载的超类中的方法。看下面的例子:class Mammal void getBirthInfo() System.out.println("born alive."); class Platypus extends Mammal v

57、oid getBirthInfo() System.out.println("hatch from eggs"); System.out.print("a mammal normally is "); super.getBirthInfo(); 在上面的例子中,使用 super.getBirthInfo() 去调用超类 Mammal 中被重载的方法。 构造器使用super去调用超类中的构造器。而且这行代码必须放在第一行,否则编译将出错。 看下面的例子:public class SuperClassDemo SuperClassDemo() class C

58、hild extends SuperClassDemo Child() super(); 在上面这个没有什么实际意义的例子中,构造器Child()包含了 super,它的作用就是将超类中的构造器 SuperClassDemo 实例化,并加到 Child 类中。编译器自动加入代码编译器自动加入代码到构造器, 对于这个, java 程序员新手可能比较混淆。 当我们写一个没 有构造器的类,编译的时候,编译器会自动加上一个不带参数的构造器,例如:public classExample 编译后将如下代码: public class Example Example() 在构造器的第一行,没有使用super,那么编译器也会自动加上,例如:public class TestConstructors TestC

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论