第五章继承:类、超类、子类

  1. 定义子类

           关键字extends表示继承

package example1;
import java.time.*;

public class Employee{
private String name;
private double salary;
private LocalDate hireDay;

public Employee(String name,double salary,int year,int month,int day){
this.name=name;
this.salary=salary;
hireDay=localDate.of(year,month,day);
}

public String getName(){
return name;
}

public double getSalary(){
return salary;
}

public localDate getHireDay(){
return hireDay;
}

public void raiseSalary(double byPercent){
double raise=salary*byPercent/100;
salary+=raise;
}

}
package example1;

public class Manager extends Employee{
    域

    方法
}

           超类:已存在的类。如上图的Employee类

           子类:新类。如上图的Manager类。

                      子类往往比父类拥有更丰富的功能。如下图代码所示。

public class Manager extends Employee{
  private double bonus;  //增加一个用于存储奖金信息的域
  ····
  public void setBonus(double bonus){    
   this.bonus=bonus;
}//增加一个用于设置这个域的新方法

}

           超类与子类的区别:

                  子类自动继承了超类的域和方法,因此子类对象可以调用父类的方法。(如Manager类型的对象可以调用Employee类中定义的getName()、getSalary()、getHireDay()、raiseSalary() )

                 而父类对象不可以调用在子类中定义的域和方法。(如Employee类型对象不可以调用Manager类型中的setBouns方法)

          设计类时的建议:

                   将通用的方法和域放于超类中,将具有特殊用途的方法和域放于子类中。

2.覆盖方法

          为什么子类需要覆盖方法?

               超类中有些方法不适用于子类。(如Manager类中的getSalary方法应该返回薪水和奖金之和)为此需要提供一个新的方法覆盖超类中这个方法。

package example1;

public class Manager extends Employee{
private double bonus;
····
public void setBonus(double bonus){
this.bonus=bonus;
}
····
public double getSalary(){
//salary域为私有域,子类方法必须通过公有接口即getSalary()才能访问私有域
//子类有自己的getSalary()方法,因此调用父类的getSalary()方法则需要加关键字super
 double baseSalary=super.getSalary();
 return baseSalary+bonus;
}//子类重新定义getSalary方法,覆盖了超类原来的getSalary方法

}

          注意:

                   子类可以增加域、增加方法或覆盖方法,但绝对不能删除继承的所有域和方法。

3.子类构造器

//子类构造器

public Manager(String name,double salary,int year,int month,int day){
  super(name,salary,year,month,day);
  bonus=0;
}

         关键字super在上图代码中与之前具有不同的含义。

super(name,salary,year,month,day);

        语句是“调用超类Employee中含有name、salary、year、month、day参数的构造器”的简写形式。 

        为什么要在子类构造器中调用超类的构造器?

                     因为子类Manager构造器中无法访问超类的私有域,必须通过超类Employee的构造器对子类继承的这部分私有域进行初始化。可以通过super实现对超类构造器的调用。super调用超类构造器必须是子类构造器的第一条语句。

                      如果子类中没有显式调用超类的构造器,系统自动调用超类默认的构造器。如果超类中没有没有参数的构造器,则Java编译器将报告错误。

4.继承层次

          继承层次:由一个公共超类派生出来的所有类的集合。

5.多态

          什么情况需要设计为继承关系?

              “is-a”规则:子类的每个对象也是超类的对象。(如每一名经理也是一名雇员)

               重置法则:即出现超类对象的任何地方可以用子类对象置换。

Employee e;
e=new Employee();
e=new Manager(); //可以将子类对象赋值给超类对象

         在Java程序设计语言中,对象变量是多态的。Employee变量可以引用Employee类对象,也可以引用Employee类的任何一个子类的对象。然而,不能将一个超类的引用赋给子类。

Manager boss=new Manager();
Employee[] staff=new Employee[3];
staff[0]=boss;
//staff[0]和boss引用同一对象,编译器将staff[0]看做Employee对象

          

 

猜你喜欢

转载自blog.csdn.net/rachel9798/article/details/82491196