首页 > 代码库 > java随笔:super关键字

java随笔:super关键字

super关键字

一、概念引入。

  1.假如你在某个公司工作,这个公司中经理的待遇与普通员工的待遇存在一些差异。不过,他们之间也存在很多相同的地方,例如,他们都能领取薪水。只是普通员工在完成本职任务以后仅领取薪水,而经理在完成了预期的业绩之后还能领到奖金。下面用部分代码表示这段信息。

1 public class Manager extends Employee{
2     //这里增加一个用于存储奖金信息的域,以及设置这个域的新方法
3     private double bonus;
4     public void setBonus(double bonus){
5         this.bonus=bonus;
6     }
7 }

  2.覆盖方法。

  由于超类中的有些方法对子类Manager并不一定适用。Manager类中的getSalary方法应该返回的是薪水与奖金的总和。为此,需要提供一个新的方法来覆盖父类中的这个方法:

1 public class Manager extends Employee{
2     //******
3     public double getSalary(){
4     //******    
5     }
6 }

  假如要实现这个方法似乎只要返回salary和bonus域的总和就可以了:

1 public class Manager extends Employee{
2     //******
3     public double getSalary(){
4         return salary+bonus;
5     }
6 }

  然而,这个方法并不能运行。因为Manager类的getSalary方法不能够直接访问超类的私有域。也就是说,尽管每个Manager对象都拥有一个名为salary的域,但在Manager类的getSalary方法中并不能够直接访问salary域。只有Employee类的方法才能够访问私有部分。如果Manager类的方法一定要访问私有域,就必须借助与公有的接口,,Employee类中的共有方法getSalary正是这样一个接口。

1 public class Manager extends Employee{
2     //******
3     public double getSalary(){
4         double baseSalary=getSalary();
5         return basesalary+bonus;
6     }
7 }

  但是这样的代码会导致无限次地调用自己,知道程序崩溃。

  总结:我们希望调用超类Employee中的getSalary方法,而不是当前类的这个方法。为此,可以使用特定的关键字super解决这个问题。

二、super作用简单介绍。

  1.super()从子类中调用父类的构造方法。

  2.在子类中访问父类被屏蔽的方法或属性。

  结合第一点Employee类中的getSalary方法。下面是Manager类中getSalary方法的正确书写格式:

1 public class Manager extends Employee{
2     //******
3     public double getSalary(){
4         double baseSalary=super.getSalary();
5         return basesalary+bonus;
6     }
7 }

  子类中可以增加减域或覆盖超类的方法,然而绝对不能删除继承的任何域和方法。

三、请允许我又扯回构造器。

 1 public class Manager extends Employee{
 2     //******
 3     private double bonus;
 4     public double getSalary(){
 5         double baseSalary=super.getSalary();
 6         return basesalary+bonus;
 7     }
 8     public Manager(String name,double salary,int year,int month,int day){
 9         super(name,salary,year,month,day);
10         bonus=0;
11     }
12 }

  由于Manager类的构造器不能访问Employee类的私有域,所以必须利用Employee类的构造器对这部分进行初始化,我们可以通过super实现对超类的调用。使用super调用构造器的语句必须是子类构造器的第一条语句。

  如果子类的构造器没有显示地调用超类的构造器,则将自动地调用超类默认(没有参数)的构造器。如果超类没有不带参的构造器,并且在子类的构造器中又没有显示地调用超类地其他构造器,则java编译会报错。

四、super与this的比较。

  有些人认为super与this引用是类似的概念,实际上,这样比较并不恰当。这是因为super不是一个对象的引用,不能将super赋给另一个对象变量,他只是一个指示编译器调用超类方法的特殊关键字。

  关键字this有两个用途:一是调用隐式参数,二是调用该类其他的构造器(like this,【this("李四",18)】)。

  关键字super也有两个用途:一是调用超类的方法,二是调用超类的构造器。

  在调用构造器的时候,这两个关键字的使用方式很相似。调用构造器的语句只能作为另一个构造器的第一条语句出现。构造参数既可以传递给本类的其他构造器,也可以传递给超类的构造器。

五、注意点。

  1.super()从子类中调用父类的构造方法,this()在同一类内调用其它构造方法。

  2.this()和super()不能同时出现在一个构造函数里面。

  3.super()和this()均需放在构造方法内第一行。

  4.this()和super()都指的是对象,所以,均不可以在static环境中使用。

java随笔:super关键字