Which Overloaded Method is Called in Java

2022-08-31 17:33:41

I have a basic inheritance situation with an overloaded method in the super class.

public class Person {
    private String name;
    private int dob;
    private String gender;

    public Person(String theName, int birth, String sex){
        name = theName;
        dob = birth;
        gender = sex;
    }

    public void work(){
        getWorkDetail(this);
    }

    public void getWorkDetail(Employee e){
        System.out.println("This person is an Employee");
    }

    public void getWorkDetail(Person p){
        System.out.println("This person is not an Employee");
    }
}

The following class extends the class above:EmployeePerson

public class Employee extends Person {

    String department;
    double salary;

    public Employee(String theName, int birth, String sex){
        super(theName, birth, sex);
        department = "Not assigned";
        salary = 30000;
    }
}

The main method simply creates an object (both static and dynamic type) and calls on it:Employee.work()

public static void main(String[] args){
    Employee e1 = new Employee("Manager1", 1976, "Female");
    e1.work();
}

This ends up printing

This person is not an Employee

Looking through this I had thought that since both the static and dynamic type of the object is it would call the overloaded method in Person that takes an as a parameter. Since I am clearly wrong about this I opened a debugger assuming the reference to "this" at the line in the class must have morphed to it's super class. However this is not what I found.e1EmployeeEmployeegetWorkDetail(this)Person

screenshot

Clearly at this point in the code is an object, however it still chose to execute the overloaded method . Can anyone explain this behavior?thisEmployeegetWorkDetail(Person p)


答案 1

Unlike method overrides, method overloads are linked based on the static type. And in this case, in only knows about the type.getWorkDetail(this)PersonPerson

Method overloading is not designed to provide dynamic runtime behavior.

To take advantage of dynamic binding, you may need to redesign your code to override the methods, instead:

public static void main(String[] args) throws IOException {
    new Employee("Manager1", 1976, "Female").getWorkDetail();
    new Person("Manager1", 1976, "Female").getWorkDetail();
}

And modify behavior based on implementing classes. Of course, you can overload methods, as long as you take care of overriding the overloaded methods too, if required.

class Person {
    private String name;
    private int dob;
    private String gender;

    public Person(String theName, int birth, String sex) {
        name = theName;
        dob = birth;
        gender = sex;
    }

    public void getWorkDetail() {
        System.out.println("This person is not an Employee");
    }
}

class Employee extends Person {

    String department;
    double salary;

    public Employee(String theName, int birth, String sex) {
        super(theName, birth, sex);
        department = "Not assigned";
        salary = 30000;
    }

    public void getWorkDetail() {
        System.out.println("This person is an Employee");
    }
}

答案 2

The overload resolution happens during compile time, not at runtime.

So, when you call , is assumed to be a (which is the static type) and hence called the corresponding overload.getWorkDetails(this)thisPerson

Note: Using inside class would have made it an type. You can verify this by overloading in like this.thisEmployeeEmployeework()Employee

class Employee extends Person {
    ...

    public void work() {
        getWorkDetails(this); // This should print "This person is an Employee"
    }
}

推荐