package inheritance;
//Manager类继承了Employee类
public class Manager extends Employee{
private double bonus;
public Manager(String n, double s, int year, int month, int day){
//利用super关键词调用Employee类的构造器
super(n, s, year, month, day);
bonus = 0;
}
//覆盖了Employee类中的getSalary方法
public double getSalary(){
//用super关键字调用Employee类的方法
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
public void setBonus(double b){
bonus = b;
}
}
package inheritance;
import java.util.Date;
import java.util.GregorianCalendar
public class Employee {
private String name;
private double salary;
private Date hireDay;
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 hireDay;
}
public void raiseSalary(double byPercent){
double raise = salary * byPercent / 100;
salary += raise;
}
}
public static void main(String[] args){
//constrcut a Manager object
Manager boss = new Manager("Cracker",80000,1988,12,15); boss.setBonus(5000);
Employee[] staff = new Employee[3]; //fill the staff arry with Manager and //Employee object
staff[0] = boss;
staff[1] = new Employee("Harry",50000,1986,10,1);
staff[2] = new Employee("Tommy",40000,1987,3,15);
//print out information about all Employee objects
//体现了多态与动态捆绑
for(Employee e : staff)
System.out.println("name:" + e.getName() + ",salary:" + e.getSalary());
}
3.上段话还提出了做出了特别的处理,完全搞不懂在哪儿?
1.什么叫暂时忽视对象的类型,使用对象的全部功能?
staff数组中对象的类型是Employee,但实际上其中保存了一个子类的对象boss。如果把boss当作Employee使用是无法使用该对象的所有方法的,
比如setBonus方法,要使用这个方法(因为boss作为Manager的实例,需要使用这个方法),就需要暂时忽略它的类型(Employee),把它当作Manager使用。
2.什么叫复原成Manager类,以便能够访问新增加的所有变量?这些新增加的变量是啥,能否指出来?
所谓的复原,修改下代码可能更清晰些:
去掉boss对象,直接给staff[0]赋值:
staff[0] = new Manager("Cracker",80000,1988,12,15);
好了,这时候直接调用staff[0].setBonus就会报错,因为此时staff[0]按照声明的类型是Employee,没有setBonus这个方法。
需要强制转换成Manager类,也就是所谓的复原成Manager类来调用:
((Manager)staff[0]).setBonus(5000);
新增加的成员变量/方法:就是Manager类中新定义的bonus变量,setBonus方法。
3.上段话还提出了做出了特别的处理,完全搞不懂在哪儿?
一些特别的处理,上面已经提到了:**,即将boss变量存入数组之前,先用Manager对象对它进行初始化。
实际上就是说,为了给staff[0] setBonus,这儿做了技巧性的处理:
先声明一个Manager类型的boss变量,调用setBonus方法之后,再把bonus赋值给staff[0].
不技巧性的做法就是强制类型转换,就是我在上一问中的代码写法:
staff[0] = new Manager("Cracker",80000,1988,12,15);
((Manager)staff[0]).setBonus(5000);
Java对数据类型是不会做自动的类型转换的,比如 int a = 4; long b = a;这样是不可以的。但是java提供了一种更强大更方便的动态绑定特性。
就是面向对象的多态,在上文的例子中,boss变量的实际类型是Manager ,但是我们在将该变量赋值给数组时则把它看做是Employee对象,
这样方便定义数组包含所有的员工数据。如果需要访问Manager所特有的bonus变量时,则编译器会将boss变量转换为Manager对象。
就是说只有在使用的时候才绑定变量的类型,这就是动态绑定
1.什么叫暂时忽视对象的类型,使用对象的全部功能?
暂时忽视对象的类型,这种情况主要发生在子类继承父类后,子类多种多样并且重写了父类的方法,而此时你只关心父类的定义的方法,但是调用的实际上确实子类的实现。此时无法使用子类自定义的属性和方法,因为类型已经从子类降级到父类。
例如,例子中,你使用了的Employee数组,但是你填充的确实Manager,Manager是集成Employee的,所有满足数组的类型要求,但是实际上你使用的Manager的实现方法(可以自己去重写父类方法进行测试)。
2.什么叫复原成Manager类,以便能够访问新增加的所有变量?这些新增加的变量是啥,能否指出来?
这个是以第一个问题的前提下发生的,子类继承了父类以外,会额外增加属性和方法,而这些方法是父类没有的,如果你需要使用这些属性和方法,需要把类型重新转换成子类。
例如,你使用了的Employee数组,但是你填充的确实Manager,这个时候你从数组里取出默认都是Employee类型,如果你要使用Manager的方法,就需要把类型重新转换成Manager。
事实上 所谓强制转换除了基本型之外 无非是包含关系才能强转 比如子类可以强转成父类 但是反之则不行