Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't overloading be implemented at excecution time?

See the following example:

interface I {}

class A implements I {}

class B implements I {}

class Foo{
    void f(A a) {}
    void f(B b) {}
    static public void main(String[]args ) {
        I[] elements = new I[] {new A(), new B(), new B(), new A()};
        Foo o = new Foo();
        for (I element:elements)
            o.f(element);//won't compile
    }
}

Why doesn't overloading methods support upcasting?

If overloading was implemented at run time, it would provide much more flexibility. E.g, the Visitor Pattern would be simpler. Is there any technical reason that prevents Java from doing this?

like image 511
Don Li Avatar asked May 23 '12 04:05

Don Li


People also ask

Can we overload method on run-time?

Do not use overloaded methods to differentiate between runtime types. Java supports overloading methods and can distinguish between methods with different signatures. Consequently, with some qualifications, methods within a class can have the same name if they have different parameter lists.

Is overloading happening at run-time or compiler time?

There are two types of polymorphism one is Compile-time polymorphism and another is run-time polymorphism. Method overloading is the example of compile time polymorphism and method overriding is the example of run-time polymorphism.

Why overloading happens at compile time?

Method overloading is the compile-time polymorphism where more than one methods share the same name with different parameters or signature and different return type. Method overriding is the runtime polymorphism having the same method with same parameters or signature but associated withcompared, different classes.

Does overloading happens at compile time?

Compile-time polymorphism is obtained through method overloading. The term method overloading allows us to have more than one method with the same name. Since this process is executed during compile time, that's why it is known as Compile-Time Polymorphism.


2 Answers

Overload resolution involves some non-trivial rules to determine which overload is the best fit, and it'd be hard to do these efficiently at runtime. In contrast, override resolution is easier -- in the hard case you have to just look up the foo function for the object's class, and in the easy case (e.g. when there's only one implementation, or only one implementation in this code path), you can turn the virtual method into a statically-compiled, non-virtual, non-dynamically-dispatching call (if you're doing it based on the code path, you have to do a quick check to verify that the object is actually the one you expect).

As it turns out, it's a good thing Java 1.4 and lower didn't have runtime override resolution, because that would make generics much harder to retrofit. Generics play a role in override resolution, but this information wouldn't be available at runtime due to erasure.

like image 172
yshavit Avatar answered Sep 27 '22 22:09

yshavit


There is no theoretical reason why it cannot be done. The Common Lisp Object System supports this type of construction — called multiple dispatch — although it does so in a somewhat different paradigm (methods, rather than being attached to objects, are instances of generics (or generic functions), which can do virtual dispatch at run-time on the values of multiple parameters). I believe there have also been extensions to Java to enable it (Multi-Java comes to mind, although that may have been multiple inheritance rather than multiple dispatch).

There may, however, be Java language reasons why it cannot be done, besides the language designers just thinking it shouldn't be done, that I'll leave others to reason about. It does introduce complications for inheritance, though. Consider:

interface A {}
interface B {}
class C implements A {}

class Foo {
    public void invoke(A a) {}
    public void invoke(B b) {}
}

class Bar extends Foo {
    public void invoke(C c) {}
}

class Baz extends Bar {
    public void invoke(A a) {}
}

Baz obj = new Baz();
obj.invoke(new C);

Which invoke is invoked? Baz? Bar? What is super.invoke? It is possible to come up with deterministic semantics, but they will likely involve confusion and surprise in at least some cases. Given that Java aims to be a simple language, I don't think features introducing such confusion are likely to be seen as according with its goals.

like image 34
Michael Ekstrand Avatar answered Sep 27 '22 22:09

Michael Ekstrand