Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading is compile-time polymorphism. Really?

Tags:

I do know the syntactical difference between overriding and overloading. And I also know that overriding is run-time polymorphism and overloading is compile-time polymorphism. But my question is: "Is overloading is really compile-time polymorphism? Is the method call really solving at compile time?". To clarify my point, let's consider an example class.

public class Greeter {     public void greetMe() {         System.out.println("Hello");     }      public void greetMe(String name) {         System.out.println("Hello " + name);     }      public void wishLuck() {         System.out.println("Good Luck");     } } 

Since all of the methods greetMe(), greetMe(String name), wishLuck() are public, they all can be overriden(including overloaded one), right? For example,

public class FancyGreeter extends Greeter {     public void greetMe() {         System.out.println("***********");         System.out.println("*  Hello  *");         System.out.println("***********");     } } 

Now, consider the following snippet:

Greeter greeter = GreeterFactory.getRandomGreeter(); greeter.greetMe(); 

The getRandomGreeter() method returns a random Greeter object. It may either return an object of Greeter, or any of its subclasses, like FancyGreeter or GraphicalGreeter or any other one. The getRandomGreeter() will create the objects either using new or dynamically load the class file and create object using reflection(I think it is possible with reflection) or any other way that is possible. All of these methods of Greeter may or may not be overriden in subclasses. So the compiler has no way to know whether a particular method(overloaded or not) is overriden. Right? Also, wikipedia says on Virtual functions:

In Java, all non-static methods are by default "virtual functions". Only methods marked with the keyword final, which cannot be overridden, along with private methods, which are not inherited, are non-virtual.

Since, virtual functions are resolved at run-time using dynamic method dispatch, and since all non private, non final methods are virtual(whether overloaded or not), they must be resolved at run-time. Right?

Then, How can overloading still be resolved at compile-time? Or, is there anything that I misunderstood, or am I missing?

like image 416
Jomoos Avatar asked Dec 02 '11 11:12

Jomoos


People also ask

Is overloading compile time polymorphism?

Method overloading is the example of compile time polymorphism and method overriding is the example of run-time polymorphism.

Does overloading happen at compile time?

Overloading happens at compile-time while Overriding happens at runtime: The binding of overloaded method call to its definition has happens at compile-time however binding of overridden method call to its definition happens at runtime.

Why is method overloading called compile polymorphism?

If a method is overloaded, the compiler decides which method is to be executed by verifying the argument list and return type at compile time. So this is "compile time polymorphism".

Why overloading is called compile time?

Static Polymorphism is also know as Early Binding and Compile time Polymorphism. Method Overloading and Operator Overloading are examples of the same. It is known as Early Binding because the compiler is aware of the functions with same name and also which overloaded function is tobe called is known at compile time.


1 Answers

Every 'Greeter' class has 3 virtual methods: void greetMe(), void greetMe(String), and void wishLuck().

When you call greeter.greetMe() the compiler can work out which one of the three virtual methods should be called from the method signature - ie. the void greetMe() one since it accepts no arguments. Which specific implementation of the void greetMe() method is called depends on the type of the greeter instance, and is resolved at run-time.

In your example it's trivial for the compiler to work out which method to call, since the method signatures are all completely different. A slightly better example for showing the 'compile time polymorphism' concept might be as follows:

class Greeter {     public void greetMe(Object obj) {         System.out.println("Hello Object!");     }      public void greetMe(String str) {         System.out.println("Hello String!");     } } 

Using this greeter class will give the following results:

Object obj = new Object(); String str = "blah"; Object strAsObj = str;  greeter.greetMe(obj); // prints "Hello Object!" greeter.greetMe(str); // prints "Hello String!" greeter.greetMe(strAsObj); // prints "Hello Object!" 

The compiler will pick out the method with the most specific match using the compile-time type, which is why the 2nd example works and calls the void greetMe(String) method.

The last call is the most interesting one: Even though the run-time type of strAsObj is String, it has been cast as an Object so that's how the compiler sees it. So, the closest match the compiler can find for that call is the void greetMe(Object) method.

like image 116
vaughandroid Avatar answered Oct 24 '22 19:10

vaughandroid