Java的this与super关键字
2016-01-15 00:07
465 查看
一、
在这里,我们给Father类写了个构造方法。创建了一个对象,并调用其set_a()方法为a赋值并打印赋值后的结果。
运行结果:
Father:constructor
Father:print a = 2
小结:
1.这段代码里,如果我们没有写这个Father()构造方法的话,也会存在一个默认的构造方法。
2.obj对象调用了set_a()方法为a赋值,注意这里的this关键字,这个this的意思是本类的对象,即“自己”。我们可能会创建很多Father类的对象,哪个对象调用set_a()方法,被赋值的a就是哪个对象的。如果把this去掉,在这里运行结果是一样的。
二、
新建一个Son类继承Father类:
运行结果:
Father:constructor
小结:
Son子类并没有写构造方法,只有默认的构造方法。但是我们通过new创建Son的对象的时候,是会调用父类的构造方法的。但是调用父类和子类的构造方法顺序如何呢?
三、
将Son类改动如下:
运行结果:
Father:constructor
Son:constructor
小结:
可以看出new一个Son对象的时候,是会先调用父类的构造方法,再调用子类的构造方法。
四、
将父类改动如下:
子类不变。
结果:
Father类可以正常运行,输出:
Father:constructor
Father:print a = 2
Son类会报错不能编译运行。
小结:
Son类报错的原因是因为创建Son对象时,需要调用父类的构造方法。但是父类的构造方法是有参数的。而我们在创建Son对象的时候并没有传入参数。
但是注意,如果我们把Son的main方法里对象的创建就这么加上参数,如Son obj = new Son(3);也是会报错不能编译运行的。
这个问题怎么解决呢?
五、
可以用super关键字来解决。
子类改为:
运行结果:
Father:constructor
Son:constructor
小结:
super()的意思是调用父类的构造方法。在这个例子里,我们在子类的构造方法里,用super()调用了父类的构造方法。因此解决了必须调用父类构造方法而又得带参数的问题。
六、
再将子类改动如下:
运行结果:
Father:constructor
Father:print a = 5
Son:constructor
小结:
super.set_a(5)运行时,会调用Father类的set_a()方法:
这里,this.a被赋值为5, 但是哪个a被赋值为5了呢?
因为调用set_a()方法的是super,也就是Father类。因此这里的this指的就是默认构造的Father对象。也就是这个Father对象的a被赋值为5了。
注意:this和super不能用在static静态方法中。假如我们在main方法里写一句this.set_a(5);或者super.set_a(5);是会报错的。因为static方法是不依赖于具体对象的,而this和super是依赖具体对象的。
public class Father { private int a = 0; public Father() { System.out.println("Father:constructor"); } public void set_a(int num) { this.a = num; System.out.println("Father:print a = " + a); } public static void main(String[] args) { Father obj = new Father(); obj.set_a(2); } }
在这里,我们给Father类写了个构造方法。创建了一个对象,并调用其set_a()方法为a赋值并打印赋值后的结果。
运行结果:
Father:constructor
Father:print a = 2
小结:
1.这段代码里,如果我们没有写这个Father()构造方法的话,也会存在一个默认的构造方法。
2.obj对象调用了set_a()方法为a赋值,注意这里的this关键字,这个this的意思是本类的对象,即“自己”。我们可能会创建很多Father类的对象,哪个对象调用set_a()方法,被赋值的a就是哪个对象的。如果把this去掉,在这里运行结果是一样的。
二、
新建一个Son类继承Father类:
public class Son extends Father { public static void main(String[] args) { Son obj = new Son(); } }
运行结果:
Father:constructor
小结:
Son子类并没有写构造方法,只有默认的构造方法。但是我们通过new创建Son的对象的时候,是会调用父类的构造方法的。但是调用父类和子类的构造方法顺序如何呢?
三、
将Son类改动如下:
public class Son extends Father { public Son() { System.out.println("Son:constructor"); } public static void main(String[] args) { Son obj = new Son(); } }
运行结果:
Father:constructor
Son:constructor
小结:
可以看出new一个Son对象的时候,是会先调用父类的构造方法,再调用子类的构造方法。
四、
将父类改动如下:
public class Father { private int a = 0; public Father(int a) {//加上参数 System.out.println("Father:constructor"); } public void set_a(int num) { this.a = num; System.out.println("Father:print a = " + a); } public static void main(String[] args) { Father obj = new Father(5); obj.set_a(2); } }
子类不变。
结果:
Father类可以正常运行,输出:
Father:constructor
Father:print a = 2
Son类会报错不能编译运行。
小结:
Son类报错的原因是因为创建Son对象时,需要调用父类的构造方法。但是父类的构造方法是有参数的。而我们在创建Son对象的时候并没有传入参数。
但是注意,如果我们把Son的main方法里对象的创建就这么加上参数,如Son obj = new Son(3);也是会报错不能编译运行的。
这个问题怎么解决呢?
五、
可以用super关键字来解决。
子类改为:
public class Son extends Father { public Son() { super(4);//加上super,并传入参数 System.out.println("Son:constructor"); } public static void main(String[] args) { Son obj = new Son(); } }
运行结果:
Father:constructor
Son:constructor
小结:
super()的意思是调用父类的构造方法。在这个例子里,我们在子类的构造方法里,用super()调用了父类的构造方法。因此解决了必须调用父类构造方法而又得带参数的问题。
六、
再将子类改动如下:
public class Son extends Father { public Son() { super(4); super.set_a(5);//super调用父类方法 System.out.println("Son:constructor"); } public static void main(String[] args) { Son obj = new Son(); } }
运行结果:
Father:constructor
Father:print a = 5
Son:constructor
小结:
super.set_a(5)运行时,会调用Father类的set_a()方法:
public void set_a(int num) { this.a = num; System.out.println("Father:print a = " + a); }
这里,this.a被赋值为5, 但是哪个a被赋值为5了呢?
因为调用set_a()方法的是super,也就是Father类。因此这里的this指的就是默认构造的Father对象。也就是这个Father对象的a被赋值为5了。
注意:this和super不能用在static静态方法中。假如我们在main方法里写一句this.set_a(5);或者super.set_a(5);是会报错的。因为static方法是不依赖于具体对象的,而this和super是依赖具体对象的。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序