//父类
public class Employee {
private String name;
private double salary;
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
public double getAnnual() {
return 12 * salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
//子类
public class Manager extends Employee {
public double bonus;
public Manager(String name, double salary, double bonus) {
super(name, salary);
this.bonus = bonus;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
public double getAnnuals() {
return (super.getAnnual() + bonus);
}
public double a() {
return getAnnuals();
}
double b = getAnnuals();
}
//
public class PloyParameter {
public static void main(String[] args) {
Manager milan = new Manager("milan", 5000, 200000);
System.out.println(milan.a());
System.out.println(milan.b);
}
}
为何milan.a.()和milan.b 两次输出的不一样呢 ?前者是260000.0后者是60000.0. 请朋友们解答疑惑一下
类的内存空间是在实例化时分配的,而类的成员变量是早于类的成员方法“诞生”的。看下面的例子:
public class A {
public void setName(String s){
this.name = s;
}
public String getName(){
return name;
}
private String name;
}
name属性的声明放在setName()方法的下面,但是setName()方法仍然能访问name属性。这说明类的成员变量是早于方法声明的,也就是说方法诞生于成员变量之后。
还有一点,在实例化子类的时候,会先调用父类的构造函数,然后再执行子类的构造函数,可以理解为“在实例化子类时同时实例化了一个父类,这个父类内存是子类内存的一部分”(当然,这么说是不对的,但是这里用来理解本题目还是可以的。)
那么,再回到这个题目中。
b是Manager 类的成员变量,b=getAnnuals();也就是在Manager milan = new Manager("milan", 5000, 200000);这里实例化子类的时候,b=getAnnuals();会调用父类的getAnnuals()方法。因为,b(成员变量)的诞生是早于类的方法的(也就是Manager 方法中的getAnnuals()还没有生成,因为b才刚刚开始创建,成员变量创建完后,才会创建方法。而在实例化子类时,隐含的实例化了一个父类空间,所以可以调用父类的getAnnuals()方法,这就是上面说的两个内容)。
而Manager 类中重写了getAnnuals()方法,所以,实例milan在a()方法中调用的是其本身的getAnnuals()方法。所以两个结果是不一样的。
milan.a()
方法每次调用都会重新调用 getAnnuals()
方法, milan.b
成员变量只会在实例化 Manager
类型时调用一次 getAnnuals()
方法,此后 milan.b
就保持不变。