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环境中使用。