Java虚方法调用

Fli*_*per 4 java polymorphism

说我有以下代码:

public class Employee
{
    public int salary = 2000;
    public void getDetails() {...}
}

public class Manager extends Employee
{
    public int salary = 5000;
    public int allowance = 8000;
    public void getDetails() {...}
}
Run Code Online (Sandbox Code Playgroud)

main()执行以下操作:

Employee emp = new Employee();
Manager man = new Manager();
emp.getDetails(); // method of Employee called, output ok.
man.getDetails(); // method of Manager called, output ok.

Employee emp_new = new Manager();
emp_new.getDetails(); // method of Manager called, ok.
System.out.println(emp_new.allowance); // problem, as Employee doesn't know about allowance. Ok

// the problem
System.out.println(emp_new.salary); // why 2000 and not 5000?
Run Code Online (Sandbox Code Playgroud)

该书说"你得到了与变量在运行时引用的对象相关的行为".好吧,当调用方法 时,我得到了Manager类的行为getDetails,但是当我访问属性时salary,我得到的是变量而不是对象的行为.这是为什么?

Era*_*ran 6

没有字段的多态性.子类中的字段隐藏了超类中具有相同名称的字段,但如果使用超类类型的变量Employee- 来访问该字段,则会获得超类的字段.

我没有看到在超类和子类中声明具有相同名称的字段的重点.如果子类可以访问超类的字段,则不应声明具有相同名称的字段.

如果必须在超类和子类中声明一个同名字段,则可以通过getter和setter方法访问该字段来实现多态.您可以覆盖子类中的getter和setter方法,以便它们访问子类的字段而不是超类的字段.

public class Employee
{
    private int salary = 2000;
    public void getSalary() {
        return salary;
    }
}

public class Manager extends Employee
{
    private int salary = 5000;
    @Override
    public void getSalary () {
        return salary;
    }
}

...

Employee emp_new = new Manager();
System.out.println(emp_new.getSalary()); // will print 5000
Run Code Online (Sandbox Code Playgroud)