一、this
在Java语言中,this用来指向当前实例对象,它的一个非常重要的作用就是用来区分对象的成员变量与方法的形参(当一个方法的形参与成员变量的名字相同时,就会覆盖成员变量)。示例如下:
class People{
String name;
//正确的写法
public People(String name){
this.name = name;
}
//错误的写法
public People(String name){
name = name;
}
}
//在上述例子中,第一个构造函数使用this.name来表示左边的值为成员变量,而不是这个构造方法的形式参数。
//对于第二个构造方法,由于这个函数中形式参数与成员变量有着相同的名字,因此对于语句name=name,等号左边和右边的两个name都代表的是形式参数
//在第二种情况下,只能通过this才能访问到成员变量
this的用法:
this指代当前对象,谁调指的就是谁。在方法中访问成员变量,默认有个this。
(1)this.成员变量名——访问成员变量
(2)this.方法名——调用方法
(3)this()——调用构造方法
二、super
super关键字:当子类重写父类的方法后,子类对象将无法访问父类被重写的方法。为了解决这个问题,Java中专题提供了一个super关键字用于访问父类的成员。
(通过super调用父类构造方法的代码必须位于子类构造方法的第一行,并且只能出现一次。)
super可以用来访问父类的方法或成员变量。当子类的方法或成员变量与父类有相同名字时也会覆盖父类的方法或成员变量,要想访问父类的方法或成员变量只能通过super关键字来访问,示例如下:
package com.haobi;
/*
* super demo
*/
class Base{
public void f() {
System.out.println("Base:f()");
}
}
class Sub extends Base{
public void f() {
System.out.println("Sub:f()");
}
public void subf() {
f();
}
public void basef() {
super.f();
}
}
public class Test4 {
public static void main(String[] args) {
Sub s = new Sub();
s.subf();
s.basef();
}
}
//程序输出结果如下:
Sub:f()
Base:f()
super的用法:
super指代当前对象的父类对象,super()调用父类的构造方法必须位于子类构造方法的第一句(在子类方法中不一定是第一句)。
(1)super.成员变量名——访问父类的成员变量
(2)super.方法名——调用父类的方法
(3)super()——调用父类的构造方法
注:子类的构造方法中必须通过super关键字调用父类的构造方法,这样可以妥善的初始化继承自父类的成员变量。如果子类的构造方法中没有调用父类的构造方法,Java编译器会自动加入对父类无参构造方法的调用。(如果父类没有无参构造方法,会有编译错误。)
三、this与super的区别
区别点 | this | super |
---|---|---|
属性访问 | 访问本类中的属性,如果本类中没有此属性,则从父类中继续查找 | 访问父类中的属性 |
方法 | 访问本类中的方法,如果本类中没有此方法,则从父类中继续查找 | 直接访问父类中的方法 |
调用构造 | 调用本类构造,必须放在构造方法首行 | 调用父类构造,必须放在子类构造方法的首行 |
特殊 | 表示当前对象 | 无此概念 |
注:
①既然this和super都可以调用构造方法,但是两者不能同时出现,因为两者调用构造时都必须放在构造方法的首行。
②无论子类如何操作,最终必须要首先调用父类中的构造方法。
四、知识点
1、请解释为何注释掉Fuse类的构造函数后,会发生编译错误?
//如下代码编译错误
package app.construction;
public class Fuse{
private String name;
//public Fuse(String name){this.name = name}
}
package app.construction
public class QuickFuse extends Fuse{}
上述代码发生编译错误的原因如下:
当编译器遇到QucikFuse类时,就会发生错误,并为其提供一个默认的构造函数。默认的构造函数没有参数,并在默认情况下会调用其超类的无参构造函数。然而,Fuse()构造函数却接受了一个字符串参数,这意味着编译器不再为Fuse类提供默认构造函数。QuickFuse的默认构造函数无法调用超类的无参构造函数,因为该构造函数并不存在。