各位大侠;先贴出原代码:
import java.lang.*;
import java.util.*;
public class EmployeeTest{
public static void main(String[] args){
Manger boss=new Manger("qiq",7777,1987,10,15);
Employee[] staff=new Employee[3];
staff[0]=boss;
boss.setBonus(500);
staff[1]=new Employee("lucy",100,2000,1,1);
staff[2]=new Employee("lilly",200,2011,1,1);
for(Employee e:staff){
System.out.println(e.getName()+e.getSalary());
} }
}
 class  Employee{
public Employee(String n,double s,int year,int month,int day){
name=n;
salary=s;
GregorianCalendar calendar=new GregorianCalendar(year,month-1,day);
hireDay=calendar.getTime();
}
public String getName(){
return name;
} public double getSalary(){
return salary;
}
public Date getHireDay(){
return(Date) hireDay.clone();
} public void raiseSalary(double byPercent){
double raise=salary*byPercent/100;
salary=salary+raise;
}
private String name;
private double salary;
private Date hireDay;
}
class Manger extends Employee{
public Manger(String n,double s,int year,int month,int day){
super(n,s,year,month,day);
bonus=0;
}
public void setBonus(double b){
this.bonus=b;
} public double getSalary(){
return super.getSalary()+bonus;
}
private double bonus;
}
书上这里说:变量staff[0]和boss引用同一个对象,但是编译器将staff[0]看成Employee对象,意味这可以这样调用:
boss.setBonus(500);
不可以这样调用:
staff[0].setBonus(500);
我的理解是BOSS是子类,staff[0]是父类,那为何输出结果的时候,staff[0]还能调用子类中的getSalary()方法,求解释~~~~~

解决方案 »

  1.   

    变量staff[0]和boss引用同一个对象这句话是对的。
    Employee e = new Manger("qiq",7777,1987,10,15);
    e的实际类型是Manger,但是声明为Employee,只能调用Employee ,
    要是要调用Manger的方法必须类型转换((Employee) e).setBonus
      

  2.   

    你说的是强制类型转换 把e转换为Manger型吗,但是为什么staff[0]可以转  但是staff[1]不可以?
    还有实际类型和声明类型有什么区别,可以把e说成是Employee类的对象变量、Manger子类的引用吗?
      

  3.   

    LZ如果清楚编译期和运行期就能理解了
    首先,程序要先编译,这个阶段属于编译期
    程序是 Employee[] staff 定义的
    所以编译器只知道staff[0]是Employee类型,至于运行期它指向哪个实例编译器并不知道
    所以staff[0].setBonus(500);是编译通不过的,因为Employee没有setBonus方法,所以如果想让编译通过,就要强行转换((Boss)staff[0]).setBonus(500);这样才能编译通过程序运行的时候叫做运行期
    上面说了,staff[?]在编译期编译器没法知道它运行期会指向什么实例
    所以staff[1]强行转换,就像staff[0]强行转换一样,可以编译通过
    但是运行期的时候,因为staff[1]指向的是Employee,父类对象不能强行转换为子类对象,所以运行期会报错注意上述情况的区别,错误分别出现在,一个是编译期出错,也就是编译没法通过,一个是运行期出错,也就是编译可以通过,但是运行时出异常
      

  4.   

    还有为什么e能调用子类中的getSalary()方法?然后我把父类中的getSalary()方法删除,程序会报错~父类中必须有子类方法的重载吗?