开发者

Dynamic method dispatching in Java [duplicate]

This question already has answers here: Java Static and Dynamic Binding, Overloading (4 answers) Closed 4 years ago.

The following is the code snipplet regarding my doubt.

class A {
    void someMethod(A param) {
        System.out.println("A");
    }
}

class C extends A {
    void someMethod(C param) {
        System.out.println("C");
    }
}

class DMD {
    public static void main(String[] args) {
        A ac = new C();
        C c = new C();
        ac.someMethod(c);
    }
}

Output:

A

but I excepted the output as

C

Because I have allocated memory for C, and A is referring to C's memory location, so if I call the method on the A reference which is pointing to C, and the argument is passed as C type, then I expect the someMethod(C开发者_开发问答) method should execute.

Can anyone please give me the proper reason for this behaviour?

Thanks in advance.


Method invocations on methods taking distinct argument types (overloading) are realized at compile time. (And this is your case)

If all 3 methods accepted argument of type A - i.e. method overriding was present, only then polymorphism would come into play and would trigger the method of C provided there is a inheritance relationship between A and C i.e. C extends A.


The decision which method to use basically has two phases: first the overload resolution, then the method dispatch. Overload resolution happens at compile-time, method dispatch at runtime.

In this example the overload resolution decides that the overload someMethod(A param) should be used because that's the only overload of someMethod defined in class A (and the static type of ac is A).

At runtime it is decided which implementation of someMethod(A param) to use, but since there is only one implementation (C.someMethod(C) does not override someMethod(A) as C is more specific than A), A.someMethod(A) is chosen.


Your code as written will not successfully compile. You cannot say "A ac = new C();" because C does not extend A. If you claim to have run this and gotten output, you must have mis-copied something from your running code into this post.

If, for the sake of argument, your code really said "A ac = new A();", then your code still wouldn't run, because A.someMethod takes an A, not a C. The statement ac.someMethod(c) executes the function A.someMethod. ac is of type A, so executing any function against ac will get the function of that name from class A. Trying to pass a parameter of type C to a function declared to take a parameter of type A will not "switch" you to using a function from a different class that does take such a parameter. Overloading only works within a class.

Perhaps what you're thinking of is an example more like this:

class A {
    public void someMethod(A a) {
        System.out.println("A");
    }

    public void someMethod(B b) {
        System.out.println("B");
    }
}

class Dmd {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        a.someMethod(b);
    }
}

This will output "B".

The difference here is that the class A has two versions of the function someMethod. One of them takes an A, one takes a B. When we call it with a B, we get the B version.

Do you see how this is different from your example? You are declaring three classes each with a function someMethod. Here we have one class with two functions both named someMethod. That's very different in Java.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜