好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java 中的 this 和 super 区别

1、简介

this 与 super 是类实例化时通往 object 类通道的打通者;this和super在程序中由于其经常被隐式的使用而被我们忽略,但是理解其作用和使用规范肯定是必须的。接下来将详述this与super的作用和区别。

2、引子

先来看两段代码,无报错代码示例:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

package com.liziba.ts;

 

/**

  * <p>

  *   父类示例代码

  * </p>

  *

  * @author: liziba

  */

public class father {

 

     private string name;

 

     public string getname() {

         return name;

     }

 

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

package com.liziba.ts;

 

/**

  * <p>

  *   子类示例代码

  * </p>

  *

  * @author: liziba

  */

public class son extends father{

 

     public son(string name) {

 

     }

   

}

此时将 father 类中的构造函数修改为有参的构造函数,

有错误的代码示例:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

package com.liziba.ts;

 

/**

  * <p>

  *   父类示例代码

  * </p>

  *

  * @author: liziba

  */

public class father {

 

     private string name;

 

     public father(string name) {

         this .name = name;

     }

 

     public string getname() {

         return name;

     }

 

}

子类代码不修改,此时子类报错:

这就是 super() 的隐式使用导致的报错,具体原因是因为子类 son 的构造函数中隐式的调用了父类的无参构造器,相当于隐式的 super() ,上面报错的代码和下面这个是等价的。

但是由于父类没有显示的申明无参构造函数,此时无参构造函数被有参构造函数覆盖了,所有super()调用无法抵达父类。

此时的解决办法有两种:

2.1 父类中声明无参构造函数

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

public class father {

 

     public string name;

 

     // 父类什么无参构造函数

     public father() {

     }

 

     public father(string name) {

         this .name = name;

     }

}

 

public class son extends father {

 

     public son(string name) {

         super (); // 可以省略

     }

}

2.2 子类显示的通过super调用父类的有参构造函数

?

1

2

3

4

5

6

7

public class son extends father {

 

     public son(string name) {

         // 调用父类的有参构造函数

         super (name);

     }

}

接下来将详细分析 this 和 super 的作用和区别。

3、this

this 相当于当前对象实例,或者当前对象的一个引用,

this有如下作用:

调用当前对象中的方法和属性 区分对象属性和方法形参 调用构造方法(必须在构造函数的第一行)

this相当于当前对象实例举例:

?

1

2

3

4

5

6

7

8

9

10

11

public class son extends father{

 

     private string homework = "java编程思想" ;

 

     public void dosomething() {

         // this 相当于当前son对象实例

         synchronized ( this ) {

 

         }

     }

}

调用当前对象中的方法和属性举例:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

public class son extends father{

 

     private string homework = "java编程思想" ;

 

     public void dosomething() {

         // this 获取当前对象的属性

         string hn = this .homework;

         // this 调用当前对象的方法

         this .dosomething2();

     }

 

     public void dosomething2() {

         // todo

     }

}

区分对象属性和方法形参举例:

?

1

2

3

4

5

6

7

8

9

10

public class son extends father{

 

     private string homework = "java编程思想" ;

 

     public son(string homework) {

         // 区分对象属性与方法形参

         this .homework = homework;

     }

    

}

调用其他构造方法举例:

?

1

2

3

4

5

6

7

8

9

10

11

12

public class son extends father{

 

     private string homework = "java编程思想" ;

 

     public son(string homework) {

         // 调用其他构造方法,必须在第一行

         this (homework, "你们未来都是架构师" );

     }

 

     public son(string homework, string name) {

     }

}

4、super

super 可以理解为父类(直接父类,如果有多层继承关系这里指的是最近的父类)对象的引用。super有如下的作用:

调用父类非私有的属性和方法 区分当前类与父类同名的属性和方法 调用父类的构造函数(必须在构造函数的第一行)

调用父类属性和方法示例:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

/**

  * 父类

  */

public class father {

 

     public string name;

 

     public void dosomething3() {

         // todo

     }

 

     public void dosomething4() {

         // todo

     }

}

 

/**

  * 子类

  */

public class son extends father{

 

    public void dosomething() {

        // 调用父类的非私有方法

        super .dosomething3();

        super .dosomething4();

     // 调用父类的非私有属性

        string name = super .name;

    }

 

}

区分当前类与父类同名的属性和方法示例:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

/**

  * 父类

  */

public class father {

 

     public string name;

 

     public void dosomething3() {

         // todo

     }

 

     public void dosomething4() {

         // todo

     }

}

 

 

/**

  * 子类代码修改成如下

  */

public class son extends father {

     public string name;

 

     public void dosomething() {

  

         // super可以区分父类方法与当前对象的方法

         dosomething3();

         dosomething4();

         super .dosomething3();

         super .dosomething4();

 

         // 区分当前父类的属性与当前类的属性

         string fathername = super .name;

         string sonname = name;

     }

 

     @override

     public void dosomething3() {

         // todo

     }

 

     @override

     public void dosomething4() {

         // todo

     }

}

调用父类的构造函数(必须在构造函数的第一行)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/**

  * 父类

  */

public class father {

 

     public string name;

 

     public father(string name) {

         this .name = name;

     }

}

 

/**

  * 子类

  */

public class son extends father {

 

     public son(string name) {

         super (name);

     }

}

5、总结

5.1 对比差异

this 基本概念:

访问本类实例属性和方法

super 基本概念:

访问父类实例属性和方法

this 查找范围:

先查找本类,不存在再查找父类

super 查找范围:

直接查找父类

this 其他功能:

单独使用表示当前对象

super 其他功能:

子类复写父类方法,用于访问父类同名方法

5.2 相同点

都是关键字,起指代作用 构造方法中必须在第一行调用其它构造函数

5.3 总结图

到此这篇关于java 中this与super区别的文章就介绍到这了,更多相关this与super内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

原文链接:https://juejin.cn/post/7027261851146649636

查看更多关于Java 中的 this 和 super 区别的详细内容...

  阅读:13次