转载自http://blog.csdn.net/hedyy/article/details/43373851
java super 深入理解
如果子类中定义的成员变量和父类中的成员变量同名时,则父类中的成员变量不能被继承,此时称子类的成员变量隐藏了父类的成员变量(如下图)。当子类中定义了一个方法,并且这个方法的名字,返回类型,用参数个数和类型和父类的某个方法完全相同时,父类的这个方法将被隐藏,既不能被子类继承下 来。如果您在子类中想使用被子类隐藏的父类的成员变量或方法就可以使用关键字super(如下图)。
使用super调用父类的构造方法
子类不继承父类的构造方法(如下图)。因此,子类如果想使用父类的构造方法,必须在子类的构造方法中使用,并且必须使用关键字super来表示()。而且super必须是子类构造方法中的头一条语句(如下图)。
NOTE:1,如果父类没有构造方法,会默认生成一个无参的空构造方法,如果子类没有直接申明super(),在编译的时候也会默认生成一个super()【因为JVM中的类加载机制加载一个类时必须要求其父类已经被加载】;2,如果父类申明了带参数的构造方法,那么继承它的子类必须要声明一个带参数的super(X x),如果不声明就会报错。3,java中所有的对象都继承了Object,所以,即使一个对象没有申明它继承了一个其他类,在构造函数中仍然有super(),不管你是否申明了它。
使用super操作被隐藏的成员变量和方法
子类中的super相当于父类中的this【PS:这样说也不是全对,因为super不可以访问父类的私有变量(如下图)】。如果您在子中想使用被子类隐藏了的父类的成员变量或方法就可以使用关键字super。比如super.x,super.play(),就是被子类隐藏的父类的成员变量x和方法play()。
一个很棒的举例:
我自认为这是一个很有趣的例子,能够帮您更深入的理解super;
1. class Father
2. {
3. public int num = 2;
4. Father()
5. {
6. getNum();
7. }
8. public void getNum()
9. {
10. System.out.println("父类getNum"+this.num);
11. }
12. }
13.
14. class Son extends Father
15. {
16. public int num=4;
17. public Son()
18. {
19. super();
20. super.getNum();
21. System.out.println("子类构造函数中"+num);
22. }
23. public void getNum()
24. {
25. System.out.println("子类getNum方法"+num);
26. }
27. }
28.
29. public class Demo
30. {
31. public static void main(String[] args)
32. {
33. new Son();
34. }
35. }
这段代码的输出结果是
子类getNum方法 0
父类getNum 2
子类构造函数中 4
您感到很奇怪的应该是第一个输出结果,主要有两点:
1,为什么super()运行的是子类的getNum。
2,为什么num的值又是0
先看下这段代码的执行顺序,下面的图片是这段代码执行的顺序(很简单打debug就可以知道怎么运行了)
1,为什么super()运行的是子类的getNum。为什么num的值又是0
在第4步的时候,这个方法已经被子类覆盖了,所以执行子类的getNum方法,子类的getNum方法中,用到了num变量,这个变量在子类中也有,所以父类的num也被子类覆盖了,从代码的执行顺序可以看出,子类中对num赋值的代码,还没执行到,所以此时num的值是0,也就是编译时候的值。即执行super()时,父类构造函数中调用的方法会被子类覆盖。
2,在第7步的时候,为什么结果是这样的?
子类中super相当于父类中的this,此时super.getNum()就是父类中的getNum()。
3,为什么super必须是子类构造方法中的头一条语句?
如果super不放在第一行,对代码做一个改动;
1. {
2. public int numF = 2;
3. Father()
4. {
5. }
6. }
7.
8. class Son extends Father
9. {
10. public int numS=4;
11. public Son()
12. {
13. numS = numF;
14. super(); //如果把super放在这里,在执行numS=numF时,numF的值是多少?肯定不是2,父类对numF赋值的代码都没执行到。这就是为什么java设计的时候要把super放在第一行,并且是不管你是否在第一行申明了super().不申明系统也会自动帮您把它申明了。
15. }
16. }
17.
18. public class Demo
19. {
20. public static void main(String[] args)
21. {
22. new Son();
23. }
24. }