Java中的super

super 是 Java 提供的一个关键字, super 用于限定该对象调用它从父类继承得到的实例变量或方法。它大概有三种的用法,不过再此之前,先要着重 讲一下方法重写(Override)的概念。

一:方法重写

对于方法重写我们可以拿最简单例子来看

例如鸟类都包含了飞翔方法,其中有一种鸟是特殊鸟类——鸵鸟,因此它也会从鸟类获得飞翔方法,但这个飞翔方法明显不适合鸵鸟,所以,鸵鸟需要重写鸟类的方法。

代码:

publicclass Bird {
  //这里指的是父类
  publicvoid fly() {
     System.out.println("我只一只鸟,我能飞");
  }
}
publicclassOstrichextends Bird {
  /*
   * 这里定义一个跟父类一样的方法;
   */
  publicvoid fly() {
     System.out.println("我只一只鸟,但我不能飞");
  }
}
publicclass TestBird {
 
  publicstaticvoid main(String[] args) {
     Ostrich f = new Ostrich();
     f.fly();
 
  }
 
}

输出的结果:

 

 这样的结果就是我们经常所说的方法重写。(Override)

方法的重写要遵循“两同两小一大”规则:

1:“两同”即方法名相同、形参列表相同

2:“两小”指的是子类方法返回值类型应比父类方法返回值类型更小或更像等,子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等;

3:“一大”指的是子类方法的访问权限应比父类方法的访问权限更大或者相等。

注意:

覆盖方法和被覆盖方法要么都是类方法,要么都是实例方法,不能一个是类方法(static),一个是实例方法。

二:super的三个用法

     1:子类隐藏父类字段情况

代码:
      publicclass Bird {
  String name = "小白";
  
}
publicclass Ostrich extends Bird {
  intname = 18; 
}
publicclass TestBird{
 
  publicstaticvoidmain(String[] args) {
    Ostrich f = newOstrich();
    System.out.println(f.name);
  }
 
}

结果:18.

这就是父类的字段被子类给覆盖啦,下面就用上super:

这就很好的把掩藏的字段给调试是出来啦。

多加一条this

 

2:调用父类中被覆盖的方法

publicclass Bird {
  publicvoid fly() {
     System.out.println("我只一只鸟,我能飞");
  }
}
publicclass Ostrich extends Bird { 
   publicvoid fly() {
      super.fly();//通过super来调用父类中的方法;
      System.out.println("我只一只鸟,但我不能飞");
   }
}
publicclass TestBird {
   publicstaticvoid main(String[] args) {
      Ostrich f = new Ostrich();
      f.fly();
   }
}

这就是类中的构造器的用法。

3:调用父类中的构造器

(1):无参

publicclass Super {
   Super(){
      System.out.println("这是父类中的无参构造器");
   }
}

publicclass SuperSon extends Super {
   SuperSon(){
      System.out.println("这是子类中的无参构造器");
   }
}
publicclass TestSuper {
   publicstaticvoid main(String[] args) {
      SuperSon Super = new SuperSon();    
   }
}

这样看再调用子类的无参构造器中就顺便调用了父类中的无参构造器

   (2):有参

publicclass Super {
   String name;
   intage;
   Super(String name,intage){
      /**
       * 在父类中建个构造器,让子类调用
       */
      this.name = name;//这里的name,age就是带参的构造器
      this.age = age;
      System.out.println("父类的名字:"+name+" 年龄:"+age);
   }
}
publicclass SuperSon extends Super {
   String sex;
   /**
    * 如果在子类中调用父类的构造器,那么父类中
    * 原先得值就会被覆盖;
    */
   SuperSon(String name,intage,String sex){
      super("阿白",34);//此时super是父类中的name,age
      //而此时引用super的类型必须跟父类中的一样
      this.sex = sex;
      System.out.println("子类的名字:"+name+" 年龄:"+age+" 性别:"+sex);
   }
   publicvoid Id() {//这个就是为了验证父类的值被覆盖;
      System.out.println("父类的名字:"+super.name+" 年龄:"+super.age);
   }
}
publicclass TestSuper {
   publicstaticvoid main(String[] args) {
      SuperSon Super = new SuperSon("小白",18,"男");  
      Super.Id();
   }
}

这样看再调用子类的有参构造器中就顺便调用了父类中的有参构造器

注意:

1:父类中的构造器有参,那么子类中的构造器必须有参。

2:

记住当引用父类中的构造器中必须在子类的构造器的首行。