java super

来源:互联网 发布:sketch软件介绍 编辑:程序博客网 时间:2024/05/01 04:16
我们已经知道,如果子类中定义的成员变量和父类中的成员变量同名时,则父类中的成员变量不能被继承,此时称子类的成员变量隐藏了父类的成员变 量。当子类中定义了一个方法,并且这个方法的名字,返回类型,用参数个数和类型和父类的某个方法完全相同时,父类的这个方法将被隐藏,既不能被子类继承下 来。如果我们在子类中想使用被子类隐藏的父类的成员变量或方法就可以使用关键字super。
 使用super调用父类的构造方法
  子类不继承父类的构造方法。因此,子类如果想使用父类的构造方法,必须在子类的构造方法中使用,并且必须使用关键字super来表示。而且super必须是子类构造方法中的头一条语句。如例:
例子24:
 class Student
     {
      int number;String name;
      Student(int number,String name)
        {
           this.number=number;this.name=name;
           System.out.println("I am"+name+"my number is"+number);
        }
     }
  class Univer_Student extends Student
    {
       boolean 婚否;
       Univer_Student(int number,String name,boolean b)
         {
             super(number,name);
             //婚否=b;
             System.out.println("婚否="+婚否);
         }
    }
public class Example4_24
   {
        public static void main(String args[])
          {
            Univer_Student zhang=new Univer_Student(9901,"和晓林",false);
          }
   }
运行结果
          am 和晓林 my number is 9901
         婚否=false.
   需要注意的是:如果在子类的构造方法中,没有显示地使用super关键字调用父类的某个构造方法,那么默认地有
   super();
语句,即调用父类的不带参数的构造方法。如果父类没有提供不带参数的构造方法,就会出现错误。
 使用super操作被隐藏的成员变量和方法
  如果我们在子中想使用被子类隐藏了的父类的成员变量或方法就可以使用关键字super。比如super.x,super.play(),就是被子类隐藏的父类的成员变量x和方法play()。
  例子25:
class Sum
     {
        int n;
        float f()
          {
            float sum=0;
            for (int i=1;i<=n;i++)
               sum=sum+i;
               return sum;
          }
     }
class Average extends Sum
     {
        int n;
        float f()
          {
            float c;
            super.n=n;
            c=super.f();
            return c/n;
           }
        float g()
         {
           float c;
           c=super.f();
           return c/2;
         }
    }
public class Example4_25
    {
      public static void main(String args[])
        {
          Average aver=new Average();
          aver.n=100;
          float result_1=aver.f();
          float result_2=aver.g();
          System.out.println("result_1="+result_1);
          System.out.println("result_2="+result_2);
        }
    }
运行结果
  result_1=50.50
  result_2=2525.0

看了上面的用法已经知道super怎么使用,不过使用super的原理和场合有必要加以研究,如下:
关键字super和继承一起建立类和它的父类的紧密联系。继承隐含地指出子类对父类所拥有的访问权限。例如,当我们要调用一个实例方法时,如果实例本身并 没有定义该方法,那我们自然地会得到它的父类中定义的同名方法。尽管会因为方法的覆盖或者使用定义与父类一样的实例或类变量(叫做“隐藏”)而失去这种访 问的权力。这就是为什么要使用super这个关键字,它显式地指出子类可以直接访问父类中的某些部分,尽管有时这种访问会因为种种原因被屏蔽了的方法在其 父类中的原始代码。

   关键字Super在构造函数的使用中是非常重要的,和方法不同,构造函数是不能继承的;因此super是访问父类中构造函数的惟一途径。在子类的构造函数 中,使用super(...)和适当的参数表可以触发对父类构造函数的一个条用,如果父类没有相应的构造函数,编译器会报错,这就是每个实例实现的初始化 的过程链。实例先把自己作为一个Object实例进行初始化,然后从它的直接子类开始按照继承链依次调用构造函数直到最后将与当前类直接相关的内容初始化完毕。

子类的构造函数如果要引用super的话,必须把super放在函数的首位,不然会出现这样的报错:
   Checket.java:10: call to super must be first statement in constructor

那么在类中用super调用父类构造函数时,为什么调用语句必须是子类的第一条语句?

答案:如果想用super继承父类构造的方法,但是没有放在第一行的话,那么在super之前的语句,肯定是为了满足自己想要完成某些行为的语句,但是又 用了super继承父类的构造方法。那么以前所做的修改就都回到以前了,就是说又成了父类的构造方法了


super是用在子类中,目的是访问直接父类中被屏蔽的成员,注意是直接父类(就是类之上最近的超类)。下面是一个综合运用super的例子,有两个类:一个Father类,一个Father类的子类Son,通过这两个类完全演示了super的用法,一下是代码:

 
package org.leizhimin;
public class Father {
 public String v="Father";
 public String x="输出了Father类的public成员变量x!!!";
 
 public Father() {
  System.out.println("Father构造方法被调用!");
 }
 
 public Father(String v){
  this.v="Father类的带参数构造方法!运行了.";
 }
 public void outinfo(){
  System.out.println("Father的outinfo方法被调用");
 
 public static void main(String[] args) {
  // TODO 自动生成方法存根
 }
}
 
package org.leizhimin;
public class Son extends Father{
 public String v="Son";
 
 public Son() {
  super();      //调用超类的构造方法,只能放到第一行.
  System.out.println("Son无参数构造方法被调用!");
  //super();      //错误的,必须放到构造方法体的最前面.
 
 
 public Son(String str){
  super(str);
  System.out.println("Son带参数构造方法被调用!");
 }
 //覆盖了超类成员方法outinfo()
 public void outinfo(){ 
  System.out.println("Son的outinfo()方法被调用");
 
 
 public void test(){
  
  String v="哈哈哈哈!";   //局部变量v覆盖了成员变量v和超类变量v
  
  System.out.println("------1-----");
  System.out.println(v);   //输出局部变量v
  System.out.println(this.v);  //输出(子类)成员变量v
  System.out.println(super.v); //输出超类成员变量v 
  
  System.out.println("------2-----");
  System.out.println(x);   //输出超类成员变量v,子类继承而来
  System.out.println(super.x); //输出超类成员变量v
  
  System.out.println("------3-----");
  outinfo();   //调用子类的outinfo()方法
  this.outinfo();  //调用子类的outinfo()方法
  super.outinfo(); //调用父类的outinfo()方法
 
 
 public static void main(String[] args) {
  new Son().test();
  
 }
}
 
子类Son运行结果:
 
Father构造方法被调用!
Son无参数构造方法被调用!
------1-----
哈哈哈哈!
Son
Father
------2-----
输出了Father类的public成员变量x!!!
输出了Father类的public成员变量x!!!
------3-----
Son的outinfo()方法被调用
Son的outinfo()方法被调用
Father的outinfo方法被调用
 
  说明:次例子仅仅为了说明super的用法,实际在设计类的时候一般都尽可能私有(private)化。
 
  通过上面的例子,下面总结一下super的用法:
       第一、在子类构造方法中要调用父类的构造方法,用“super(参数列表)”的方式调用,参数不是必须的。同时还要注意的一点是:“super(参数列表)”这条语句只能用在子类构造方法体中的第一行。
       第二、当子类方法中的局部变量或者子类的成员变量与父类成员变量同名时,也就是子类局部变量覆盖父类成员变量时,用“super.成员变量名”来引用父类 成员变量。当然,如果父类的成员变量没有被覆盖,也可以用“super.成员变量名”来引用父类成员变量,不过这是不必要的。
       第三、当子类的成员方法覆盖了父类的成员方法时,也就是子类和父类有完全相同的方法定义(但方法体可以不同),此时,用“super.方法名(参数列表)”的方式访问父类的方法。
       第四、super关键字只能用在类体中非静态部分,比如构造函数与成员方法中,若在main函数中调用或静态方法中编译会出错,报Cannot use super in static context的错误!
0 0