Reputation: 223
Does runtime polymorphism always happen with method overriding, or does it happen only if method is called after assigning sub class object to super class variable, during method overriding?
class A {
public void myFunc() {
System.out.println("Something");
}
}
class B extends A {
public void myFunc() {
System.out.println("Something else");
}
public static void main (String args[]) {
A obj = new B();
obj.myFunc(); //Is only this call resolved at run time?
A obj2 = new A();
obj2.myFunc(); //Or is this call too resolved at run time?
B obj3 = new B();
obj3.myFunc(); //Is this call resolved at compile time?
}
}
Upvotes: 8
Views: 1530
Reputation: 1
Generally the concept of polymorphism is related to using different forms of one type (class/interface), thats why the sub classes needs to have the similar contract as per the super type.
Considering your question all the three statements will be resolved at runtime but only the first one comes under the hood of polymorphism.
Upvotes: 0
Reputation: 44128
Whether the compiler is actually able to optimize any or all of the three method invocations and resolve the calls at compile time now or in some future implementation is irrelevant: All three method invocations are examples of runtime polymorphism, also known as dynamic dispatch This is contrasted with what is referred to as static polymorphism, also known as method overloading, which is a class having multiple methods with the same name but with different argument types.
Here is a small Java program:
public class Test {
public void foo(String inputString)
{
System.out.println(inputString);
}
public static void main(String[] args) {
Test test = new Test();
test.foo("a"); # very obvious method invocation
}
}
It is very clear to a human what method would be invoked at runtime. Here is the disassembled bytecode:
Compiled from "Test.java"
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void foo(java.lang.String);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: aload_1
4: invokevirtual #3 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
7: return
public static void main(java.lang.String[]);
Code:
0: new #4 // class Test
3: dup
4: invokespecial #5 // Method "<init>":()V
7: astore_1
8: aload_1
9: ldc #6 // String a
11: invokevirtual #7 // Method foo:(Ljava/lang/String;)V
14: return
}
Instruction 11 is a runtime dispatch of a virtual method.
But as I said, even if in some future compiler implementation this was optimized to a different call, that would just be an implementation detail.
Upvotes: 5
Reputation: 7785
Polymorphism is a principle in object oriented programming: write the logic of your software without caring of implementations The right implementation of code to be executed is ( at least in principle ), is always determined at runtime
Your doubt is about this example: A a = new A();
but it's equivalent to this A a = MyFactory.get();
Maybe JVM performs some optimization final A a = new B();
to avoid searching the right implementation ?
Upvotes: 0
Reputation: 136
Private, final and static members (methods and variables) use static binding.
While for virtual methods (In Java methods are virtual by default) binding is done at run time based upon the object held by the variable.
So to answer your question, Method Resolution always done at runtime for all of the below cases. (Whether the subclass' object assigned to superclass' variable or same type of object held by the variable)
A obj = new B();
obj.myFunc();
A obj2 = new A();
obj2.myFunc();
B obj3 = new B();
obj3.myFunc();
Upvotes: 0
Reputation: 61
In method overriding, method resolution always takes care by JVM based on the RUN TIME OBJECT. Yes, all these calls will get resolved at run-time.
A obj = new B();
obj.myFunc();
A obj2 = new A();
obj2.myFunc();
B obj3 = new B();
obj3.myFunc();
Upvotes: 6