Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java virtual method invocation

Say I have the following code:

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() {...}
}

and a main() that does the following:

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?

The book says "you get the behavior associated with the object to which the variable refers at runtime". Ok, I get behavior of Manager class when a method getDetails is called, but when I access an attribute salary, I get behavior of variable and not the object. Why is that?

like image 930
nimbudew Avatar asked Feb 11 '23 02:02

nimbudew


1 Answers

There's no polymorphism of fields. A field in a sub-class hides a field with the same name in the super-class, but if you use a variable of the super-class type - Employee - to access the field, you get the field of the super-class.

I don't see the point in declaring fields having the same name in both the super-class and the sub-class. If the sub-class has access to the field of the super-class, it shouldn't declare a field of the same name.

If you must declare a field of the same name in both super-class and sub-class, you can achieve polymorphism by accessing the field via getter and setter methods. You can override the getter and setter methods in the sub-class, so that they access the field of the sub-class instead of the field of the super-class.

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
like image 120
Eran Avatar answered Feb 13 '23 07:02

Eran