Java-this、super关键字(认真分析)

一、this关键字

  this关键字只能用于方法体内,当创建一个对象时候,JVM就会为这个对象分配一个资深的指针,就是this。因此this只能在非静态方法中使用,静态方法和静态的代码块中绝对不能使用this,this只和特定的对象关联,不和类关联,同一个类的不同对象有不同的this。

举个栗子:

 1 package cn.zpoor.Test;
 2 /**
 3  * @author 薛定谔的猫
 4  * 测试this*/
 5 public class Main {
 6     private String name;
 7     private int age;
 8     private String sex;
 9     private int i = 33;
10     //一个参数的构造器
11     public Main(int n) {
12         age = n;//可以写成this.age = age;
13     }
14     
15     //带有两个参数的构造器
16     public Main(int age,String name,String sex) {
17         //成员变量和参数同名,成员变量被屏蔽,用this来访问成员变量
18         this.name = name;
19         this.sex = sex;
20     }
21     
22     //默认构造器
23     public Main() {
24         this(0, null, null);//this调用另一个构造方法,并且只能放在第一行。
25     }
26     
27     public Main(String name) {
28         this(0, name, "man");
29     }
30     
31     
32     private void info(Main m) {
33         System.out.println("-------------");
34         System.out.println(m.name);
35         System.out.println(m.age);
36         System.out.println(m.sex);
37         this.f();//写可以写成this.f();
38     }
39     
40     private void f() {
41         //局部变量和成员变量相同,成员变量被屏蔽,用this来访问成员变量
42         int i;
43         i = this.i++;
44         System.out.println(i);
45         System.out.println(this.i);
46     }
47     
48     //返回当前实例的引用
49     
50     private Main getSelf() {
51         return this;
52     }
53     
54     
55     public static void main(String[] args) {
56         Main m1 = new Main();
57         Main m2 = new Main("zpoor");
58         m1.info(m1);
59         m2.info(m2);
60     }
61 }
62 
63 /*-------------
64 null
65 0
66 null
67 33
68 34
69 -------------
70 zpoor
71 0
72 man
73 33
74 34
75 
76 */

不要慌(冷静分析):

  一、通过this调用另一个构造方法,this(参数列表),仅仅在构造函数,别的地方不能用,而且要放在构造方法中的第一行

  二、方法的参数或者方法中的局部变量和成员变量重名的情况下,成员变量被屏蔽,就要用this.成员变量来引用成员变量。如果没有重名用不用都不为过。

  三、在方法中,引用该方法所属类的当前对象时候,直接用this

总结:this是指向对象本身的一个指针。

二、super关键字

  super和this类似,是被屏蔽的成员变量或者成员方法,或者是引用被屏蔽的成员变量和成员方法,一般都是发生在继承里面,super用在子类里面,用来访问父类中屏蔽的成员

举个栗子:

 1 package cn.zpoor.Test;
 2 /**
 3  * @author 薛定谔的猫
 4  * 测试super*/
 5 public class Father {
 6     public String Value = "Father";
 7     public String x = "Father中的成员变量";
 8     
 9     public Father() {
10         System.out.println("Father的构造器被调用");
11     }
12     
13     public Father(String Value) {
14         this.Value = "Father带参数的构造器运行了";
15     }
16     
17     public void info() {
18         System.out.println("Father的info方法被调用");
19     }
20     public static void main(String[] args) {
21         new Son().test();
22     }
23 }
24 
25 class Son extends Father {
26     public String Value = "Son";
27     
28     public Son() {
29         super();//调用父类的构造方法,只能必须放在第一行
30         System.out.println("Son的无参方法被调用");
31     }
32     
33     public Son(String name) {
34         super(name);
35         System.out.println("Son带参数的构造器被调用");
36     }
37     
38     //重写父类info方法
39     public void info() {
40         System.out.println("Son的info方法被调用");
41     }
42     
43     public void test() {
44         String Value = "老铁,得劲不?";//局部变量覆盖成员变量和超类成员变量
45         System.out.println("-----1-----");
46         System.out.println(Value);//输出局部变量Value
47         System.out.println(this.Value);//输出子类成员变量
48         System.out.println(super.Value);//输出父类的成员变量
49         
50         System.out.println("------2-----");
51         System.out.println(x);//输出超类成员变量x,子类继承来的
52         System.out.println(super.x);//输出曹磊成员变量x
53         
54         System.out.println("--------3------");
55         info();//调用子类的info方法
56         this.info();//调用子类的info方法
57         super.info();//调用超类的info方法
58     }
59 }
60 
61 /*
62 Father的构造器被调用
63 Son的无参方法被调用
64 -----1-----
65 老铁,得劲不?
66 Son
67 Father
68 ------2-----
69 Father中的成员变量
70 Father中的成员变量
71 --------3------
72 Son的info方法被调用
73 Son的info方法被调用
74 Father的info方法被调用
75 */

总结(拿烟的手微微颤抖):

  一、子类构造方法要调用父类的构造方法,super(参数列表),参数不是必须的,但是放在第一行是一定的。

  二、当子类的局部变量或者子类的局部变量和父类的成员变量重名,也就是子类变量覆盖父类变量的时候,super.成员变量来引用父类的成员变量,如果没有覆 盖,就不需要了,但是最好这样,这是一个好习惯。

  三、当子类的成员方法覆盖了父类的成员方法,就是子类的方法定义和父类的方法相同(重写,覆盖),super.方法名(参数列表)来调用父类的成员变量。

不行了,烟烫手。

原文地址:https://www.cnblogs.com/zpoor/p/7648118.html