一、this
关键字this只能使用在方法体内,当创建一个对象时,java虚拟机会给这个对象分配一个引用自身的指针,这个指针就是this。因此this只能在非静态方法(static)中使用,静态方法和静态代码块中绝对不能出现this。这在“Java关键字static、final使用总结”一文中给出了明确解释。并且this只和特定的对象关联,而不合类关联,同一个类的不同对象有不同的this。
1、可以表示构造函数的传递。this(a,b)表示调用另外一个构造函数。这里的this是个特殊语法,不是变量,也没有类型。
public class ChildA {
public ChildA(){
this(1); //调用有参构造函数ChildA(Integer age)
//super();
System.out.println("无参ChildA");
}
public ChildA(Integer age){
//super(age);
System.out.println("有参ChildA:"+age);
}
public static void main(String[] args) {
ChildA c = new ChildA();
//c = new ChildA(1);
}
}
输出结果:
有参ChildA:1
无参ChildA
2、局部变量与类变量同名,通过this去调用类变量。
方法内的局部变量与类变量同名时,类变量会被屏蔽,要想调用类变量,需用到this。
public class ChildA {
int age = 15;
public ChildA(){
int age = 10;
//调用有参构造函数ChildA(Integer age)
//super();
System.out.println("年纪:"+this.age);
}
public static void main(String[] args) {
ChildA c = new ChildA();
//c = new ChildA(1);
}
}
输出结果:
年纪:15
3、类变量和参数相同时,通过this去调用类变量
类成员变量和参数名相同时,类成员变量会被屏蔽,可通过this去调用。
public class ChildA {
int age =15;
public ChildA(){
this(1); //调用有参构造函数ChildA(Integer age)
//super();
}
public ChildA(Integer age){
//super(age);
this.age = age;//通过this对类成员变量重新赋值
System.out.println("年纪:"+this.age);
}
public static void main(String[] args) {
ChildA c = new ChildA();
//c = new ChildA(1);
}
}
4、方法调用同一个java类方法也可以用this
public class ChildA {
int age =15;
public ChildA(){
this(1); //调用有参构造函数ChildA(Integer age)
//super();
this.a();//调用方法a()
}
public ChildA(Integer age){
//super(age);
this.age = age;//通过this对类成员变量重新赋值
System.out.println("年纪:"+this.age);
}
private void a(){
System.out.println("方法a");
}
public static void main(String[] args) {
ChildA c = new ChildA();
//c = new ChildA(1);
}
}
输出结果:
年纪:1
方法a
二、super
super关键和this作用类似,是被屏蔽的成员变量或者成员方法或变为可见,或者说用来引用被屏蔽的成员变量和成员成员方法。
不过super是用在子类中,目的是访问直接父类中被屏蔽的成员,注意是直接父类(就是类之上最近的超类)。
父类:
public class Father {
public int age;
public Father(){
System.out.println("父类.构造函数.无参数.age:"+age);
}
public Father(Integer age){
System.out.println("父类.构造函数.有参数.age:"+age);
}
public void value(){
age = 1;
System.out.println("父类.函数.无参数.age:"+age);
}
}
1、通过super()或者super(参数名)方式去调用父类构造函数
子类:
public class ChildA extends Father{
int age =15;
public ChildA(){
super();
}
public ChildA(Integer age){
super(age);
}
private void a(){
System.out.println("方法a");
}
public static void main(String[] args) {
ChildA c = new ChildA();
c = new ChildA(111);
}
}
输出结果:
父类.构造函数.无参数.age:0
父类.构造函数.有参数.age:111
2、通过super.方法名(参数名)来调用父类方法
public class ChildA extends Father{
int age =15;
public ChildA(){
super();
}
public ChildA(Integer age){
super(age);
super.value();
}
private void a(){
System.out.println("方法a");
}
public static void main(String[] args) {
ChildA c = new ChildA();
c = new ChildA(111);
}
}
运行结果:
父类.构造函数.无参数.age:0
父类.构造函数.有参数.age:111
父类.函数.无参数.age:1
3、通过super.变量名来调用父类成员变量
public class ChildA extends Father{
int age =15;
public ChildA(){
super();
}
public ChildA(Integer age){
super(age);
age = super.age;
System.out.println("年龄:"+age);
}
private void a(){
System.out.println("方法a");
}
public static void main(String[] args) {
ChildA c = new ChildA();
c = new ChildA(111);
}
}
运行结果:
父类.构造函数.无参数.age:0
父类.构造函数.有参数.age:111
年龄:0
通过上面的例子,下面总结一下super的用法:
第一、在子类构造方法中要调用父类的构造方法,用“super(参数列表)”的方式调用,参数不是必须的。同时还要注意的一点是:“super(参数列表)”这条语句只能用在子类构造方法体中的第一行。
第二、当子类方法中的局部变量或者子类的成员变量与父类成员变量同名时,也就是子类局部变量覆盖父类成员变量时,用“super.成员变量名”来引用父类成员变量。当然,如果父类的成员变量没有被覆盖,也可以用“super.成员变量名”来引用父类成员变量,不过这是不必要的。
第三、当子类的成员方法覆盖了父类的成员方法时,也就是子类和父类有完全相同的方法定义(但方法体可以不同),此时,用“super.方法名(参数列表)”的方式访问父类的方法。
参考博客:https://www.cnblogs.com/bluestorm/archive/2011/12/23/note20111223.html