ImageVerifierCode 换一换
格式:DOCX , 页数:33 ,大小:28.87KB ,
资源ID:11806826      下载积分:10 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11806826.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(父类与子类.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

父类与子类.docx

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

2、= new Platypus(digger); Platypus p2 = new Platypus(); 在上面的代码中,有2个不同参数列表的构造器。第一个构造器,给类的成员name赋值,第二个构造器,调用第一个构造器,给成员变量name一个初始值 John/Mary Doe. 在构造器中,如果要使用关键字this,那么,必须放在第一行,如果不这样,将导致一个编译错误。 super的用法 构造器和方法,都用关键字super指向超类,但是用的方法不一样。方法用这个关键字去执行被重载的超类中的方法。看下面的例子: class Mammal void getBirthInfo() System.o

3、ut.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.getBirthInfo()去调用超类Mammal中被重载的方法。 构造器使用super去调用超类中的构造器。而且这行代码必须放在第一行,否则编译将出错。看下面的例子: public class SuperClassD

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

5、ple() 在构造器的第一行,没有使用super,那么编译器也会自动加上,例如: public class TestConstructors TestConstructors() 编译器会加上代码,如下: public class TestConstructors TestConstructors() super; 仔细想一下,就知道下面的代码 public class Example 经过会被编译器加代码形如: public class Example Example() super; 继承 构造器是不能被继承的。子类可以继承超类的任何方法。看看下面的代码: public class Exa

6、mple public void sayHi system.out.println(Hi); Example() public class SubClass extends Example this 指向同一个类中另外一个构造器,在第一行 指向当前类的一个实例,不能用于静态方法 super 调用父类的构造器,在第一行 调用父类中一个重载的方法 继承 构造器不能被继承 方法可以被继承 编译器自动加入一个缺省的构造器 自动加入(如果没有) 不支持 编译器自动加入一个缺省的调用到超类的构造器 自动加入(如果没有) +JAVA技术专题综述之构造方法篇+类的继承机制使得子类可以使用父类的功能(即代码),

7、并且子类也具有父类的类型。下面介绍类在继承关系上的初始化的顺序问题。 示例1: class SuperClass SuperClass() System.out.println(SuperClass constructor); public class SubClass extends SuperClass SubClass() System.out.println(SubClass constructor); public static void main(String args) SubClass sub = new SubClass(); 输出结果: SuperClass constru

8、ctor SubClass constructor 在子类中只实例化了一个子类对象。从输出结果上看,程序并不是一开始就运行自己的构造方法,而是先运行其父类的默认构造方法。注意:程序自动调用其父类的默认构造方法。 示例2: class SuperClass SuperClass(String str) System.out.println(Super with a string.); public class SubClass extends SuperClass SubClass(String str) System.out.println(Sub with a string.); publi

9、c static void main(String args) SubClass sub = new SubClass(sub); 在JDK下编译此程序不能成功。正如上例中说的:程序在初始化子类时先要寻找其父类的默认构造方法,结果没找到,那么编译自然不能通过。 解决这个问题有两个办法: 1在父类中增加一个默认构造方法。 2在子类的构造方法中增加一条语句:super(str); 且必须在第一句。 这两种方法都能使此程序通过编译,但就本程序来说运行结果却不相同。 第1种方法的运行结果是:Sub with a string. 第2种方法的运行结果是: Super with a string. Sub

10、 with a string. 第2种解决方法实际上是指定编译器不要寻找父类的默认构造方法,而是去寻找带一个字符串为参数的构造方法。 下面介绍对象的初始化顺序问题。 示例3: class One One(String str) System.out.println(str); class Two One one_1 = new One(one-1); One one_2 = new One(one-2); One one_3 = new One(one-3); Two(String str) System.out.println(str); public class Test public s

11、tatic void main(String args) System.out.println(Test main() start.); 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

12、str) System.out.println(str); class Two 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(two-1); Syste

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

14、one_3 = new One(one-3); Two(String str) System.out.println(str); 3 public class Test static Two two_3 = new Two(two-3); public static void main(String args) System.out.println(Test main() start.); Two two_1 = new Two(two-1); System.out.println(-); Two two_2 = new Two(two-2); 输出结果: one-3 one-1 one-2

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

16、(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.); System.out.println(Two.i = + Two.i); 4 输出结果: Test main() start. one-2 one-3 Two.i = 0 不仅第1次创建对象时,类中所有的静态变量要初始化,第1次访问类中的静

17、态变量(没有创建对象)时,该类中所有的静态变量也要按照它们在类中排列的顺序初始化。 综上所述:在创建对象时,对象所在类的所有数据成员会首先进行初始化,如果其中的成员变量有对象,那么它们也会按照顺序执行初始化工作。在所有类成员初始化完成后,才调用对象所在类的构造方法创建对象。构造方法作用就是初始化。 静态对象(变量)在非静态对象前初始化。静态对象(变量)只初始化一次,再次调用就不初始化了,但非静态对象在每次调用时都要初始化。 程序中的主类的静态变量会在main()方法执行前进行初始化工作。 不仅第1次创建对象时,类中所有的静态变量要初始化,第1次访问类中的静态变量(没有创建对象)时,该类中所有的

18、静态变量也要按照它们在类中排列的顺序初始化。 初始化的顺序包括构造方法调用的顺序如下: 1主类的静态成员首先初始化。 2主类的超类的构造方法按照从最高到最低的顺序被调用。 3主类的非静态对象(变量)初始化。 4调用主类的构造方法。 在一个构造方法中只能调用一次其它的构造方法,并且调用构造方法的语句必须是第一条语句。+深入剖析java类的构造方式+概要:本文通过查看一个精心构造的类结构的运行输出和使用javap工具查看实际生成的java字节码(bytecode)向java程序员展示了一个类在运行时是如何构造生成的。关键字: java 构造 javap 字节码 bytecode 按照java规范,

19、一个类实例的构造过程是遵循以下顺序的:1.如果构造方法(constructor,也有翻译为构造器和构造函数的)是有参数的则进行参数绑定。2.内存分配将非静态成员赋予初始值(原始类型的成员的值为规定值,例如int型为0,float型为0.0f,boolean型为false;对象类型的初始值为null),静态成员是属于类对象而非类实例,所以类实例的生成不进行静态成员的构造或者初始化,后面将讲述静态成员的生成时间。3.如果构造方法中存在this()调用(可以是其它带参数的this()调用)则执行之,执行完毕后进入第6步继续执行,如果没有this调用则进行下一步。4.执行显式的super()调用(可以

20、是其它带参数的super()调用)或者隐式的super()调用(缺省构造方法),此步骤又进入一个父类的构造过程并一直上推至Object对象的构造。5.执行类申明中的成员赋值和初始化块。6.执行构造方法中的其它语句。现在来看看精心构造的一个实例: class Parentint pm1;int pm2=10;int pm3=pmethod();System.out.println(Parents instance initialize block); public static int spm1=10;staticSystem.out.println(Parents static initial

21、ize block);Parent()System.out.println(Parents default constructor);static void staticmethod()System.out.println(Parents staticmethod); int pmethod()System.out.println(Parents method);return 3;class Child extends Parentint cm1;int cm2=10;int cm3=cmethod();Other co;public static int scm1=10;System.out

22、.println(Childs instance initialize block); staticSystem.out.println(Childs static initialize block);Child()co=new Other();System.out.println(Childs default constructor);Child(int m)this();cm1=m;System.out.println(Childs self-define constructor);static void staticmethod()System.out.println(Childs st

23、aticmethod);int cmethod()System.out.println(Childs method);return 3;class Otherint om1;Other() System.out.println(Others default constructor); public class InitializationTestpublic static void main(String args)Child c;System.out.println(program start);System.out.println(Child.scm1);c= new Child(10);

24、System.out.println(program end); 进入此文件所在的目录,然后编译此文件:javac InitializationTest.java运行此程序:java ?classpath . InitializationTest得到的结果是: program startParents static initialize blockChilds static initialize block10Parents methodParents instance initialize blockParents default constructorChilds methodChilds

25、 instance initialize blockOthers default constructorChilds default constructorChilds self-define constructorprogram end 如果没有看过上面的关于类的构造的说明,很容易让人误解为类的构造顺序是如下的结果(忽略参数绑定、内存分配和非静态成员的缺省值赋值):1.完成父类的非静态成员初始化赋值以及执行初始化块(这个的先后顺序取决于源文件中的书写顺序,可以将初始化块置于成员声明前,那么先执行的将是初始化块,将上面的代码稍稍变动一下就可以验证这一点。)2.调用父类的构造方法完成父类构造。3

26、.完成非静态成员的初始化赋值以及执行初始化块。4.调用构造方法完成对象的构造,执行构造方法体中的其它内容。如果根据以上java规范中给出的顺序也可以合理的解释程序的输出结果,那么如何亲眼看到是规范中的顺序而不是以上根据程序的输出推断的顺序呢?下面就使用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 ;Child();Child(int);int cmethod();static void staticmethod();Method static 0 bipush 102 putstatic #22 5 getstatic #20 8 ldc #5 10 invokevirtual #21 13 returnM

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1