Which Overloaded Method is Called in Java

method overloading in java w3schools
method overloading in inheritance in java
method overloading and method overriding in java
method overloading rules in java
method overloading in java pdf
method overloading in c++
advantages of method overloading in java
why we use method overloading in java

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 Employee class extends the Person class above:

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 Employee object (both static and dynamic type) and calls .work() on it:

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 e1 is Employee it would call the overloaded method in Person that takes an Employee as a parameter. Since I am clearly wrong about this I opened a debugger assuming the reference to "this" at the line getWorkDetail(this) in the Person class must have morphed to it's super class. However this is not what I found.

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

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

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");
    }
}

Which Overloaded Method is Called in Java, Unlike method overrides, method overloads are linked based on the static type. And in this case, getWorkDetail(this) in Person only knows about the Person type​  Overloading always occur in the same class (unlike method overriding). Method overloading is one of the ways through which java supports polymorphism. Method overloading can be done by changing number of arguments or by changing the data type of arguments. If two or more method have same name and same parameter list

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

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

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

class Employee extends Person {
    ...

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

Different ways of Method Overloading in Java, The compiler does not consider the return type while differentiating the overloaded method. But you cannot declare two methods with the same signature and  When an overloaded method is called, Java looks for a match between the arguments used to call the method and method's parameters. However, this match need not always be exact. In several cases, Java's automatic type conversions can act a role in overload resolution.

Problem specific solution

In some languages parameters are resolved to their dynamic type, but not in java. The compiler already determines at compile time where your getWorkDetail(this); will go. this is of type Person, so getWorkDetail(Person e) is called. In your specific case the solution is quite obvious. As others have already pointed out, you'll need to override getWorkDetail() in the Employee class.

Resolving methods to their dynamic parameter types

To solve the general problem of resolving parameter types at runtime, using the instanceof operator should be avoided, as it usually leads to unclean code.

If you have two different classes, a solution as simple as stated above is no longer possible. In these cases you'll have to use the visitor pattern.

Consider the following classes:

public interface Animal {
    default void eat(Food food) {
        food.eatenBy(this);
    }

    void eatMeat(Meat meat);

    void eatVegetables(Vegetables vegetables);
}

public class Shark implements Animal {
    public void eatMeat (Meat food) {
        System.out.println("Tasty meat!");
    }

    public void eatVegetables (Vegetables food) {
        System.out.println("Yuck!");
    }
}

public interface Food {
    void eatenBy(Animal animal);
}

public class Meat implements Food {
    public void eatenBy(Animal animal) {
        animal.eatMeat(this);
    }
}

public class Vegetables implements Food {
    public void eatenBy(Animal animal) {
        animal.eatVegetables(this);
    }
}

Which you can call like this:

Animal animal = new Shark();
Food someMeat = new Meat();
Food someVegetables= new Vegetables();
animal.eat(someMeat);        // prints "Tasty meat!"
animal.eat(someVegetables);  // prints "Yuck!"

Following the visitor pattern calling Animal.eat will call Food.eatenBy, which is implemented by both Meat and Vegetables. Those classes will call the more specific eatMeat or eatVegetables method, which uses the correct (dynamic) types.

Overloading in Java, However, Overloading methods on return type are possible in cases where the data type of the function being called is explicitly specified. Look at the examples​  5. The private methods can be overloaded in Java. 6. The final methods can be overloaded in Java. 7. The main method can also be overloaded in Java. 8. Both static and instance methods can be overloaded in Java. Method overloading is possible when two or more static methods with the same name, but the difference in the list of parameters.

Call preference

class Foo {
    static void test(int arg) { System.out.println("int"); }
    static void test(float arg) { System.out.println("float"); }
    static void test(Integer arg) { System.out.println("Integer"); }
    static void test(int... arg) { System.out.println("int..."); }

    public static void main(String[] arg) {
        test(6);
    }
}

The output will be int printed on console. Now you comment the first test() method and see what is the output coming.

This is the preference hirarchey in primitive data types. Now coming to derived types declare a class FooChild like this

class FooChild extends Foo {

}

and create two new methods in Foo like

static void testChild(Foo foo) { System.out.println("Foo"); }
static void testChild(FooChild fooChild) { System.out.println("FooChild"); }

then in main method try calling testChild like this testChild(new FooChild());.

Guide to Overloading Methods in Java, Calling the setDetails() method with a certain set of arguments will determine which method will be called. If no signature corresponds to your set of arguments, a  Since Java can differentiate method signatures, it can afford method overloading. Let's define a class with an overloaded method: Here, there's a method called setDetails() in several different forms. Some require just a String details, while some require a street, city, state, zip etc.

getWorkDetail(this) does not know what the subclasses are. call getWorkDetail instead.

Overloading and Overriding, Method overloadingEdit. In a class, there can be several methods with the same name. However they must have a different signature. The signature of a method  You have println() method which takes String, int, float,double or even char in output. All of those methods are collectively referred as an overloaded method in Java. The difference between method overloading and overriding is also a popular Java interview question.

Incremental Java Overloading Methods, Having two or more methods named the same in the same class is called overloading. It's not overloading if you have the same method name in two different  Java Method Overloading - If a class of a Java program has a plural number of methods, and all of them have the same name but different parameters (with a change in type or number of arguments), and programmers can use them to perform a similar form of functions, then it is known as method overloading.

Dive into Java Method Overloading, Still the same because JVM is still in confusion that which method​ is being called. So again it's a compile time error. Now the question is “Can we overload main  In java, Method Overloading is not possible by changing the return type of the method only. 1) Method Overloading: changing no. of arguments. In this example, we have created two methods, first add() method performs addition of two numbers and second add method performs addition of three numbers.

Java Method Overloading, Having more than one method with the same name in a class hierarchy is called overloading. The same method name can be reused (overloaded) as long as the​  Here method disp() is overloaded based on sequence of data type of parameters – Both the methods have different sequence of data type in argument list. First method is having argument list as (char, int) and second is having (int, char). Since the sequence is different, the method can be overloaded without any issues.

Comments
  • IMHO, the parent class shouldn't know anything about the child classes. By that i mean there is no place in the Person class for getWorkDetail(Employee e) method...
  • @zlakad I think those fuctions were meant to be static?
  • @StarWeaver, static or not, what's the difference in this particular question?
  • this in the class Person is of the static type Person.
  • As @zlakad alludes to, this class structure is poorly formed. this is implicit a non-static method. It really doesn't make any sense to pass this to a member method here.
  • @Ernest Kiwele Thank you! I was not aware Java does not provide dynamic behavior for method overloads. This clears things up.
  • Also you may want to note that, the JVM first looks up for non-overridden methods that have the signature you are specifying before looking for overridden methods that match your signature. But ideally you want to leverage Java's inheritance mechanism to restructure your code just as @Ernest shows