I have a little confusion with Dynamic Binding in java.
Here is a program, I want to know that, is there dynamic binding occurs or something else.
What dynamic binding actually is?
class A {
int a;
public A() {
a = 9;
}
public void show() {
System.out.print("show in A ; ");
System.out.println("a : " + a);
}
}
public class B extends A {
public B() {
a = 8;
}
public void show() {
System.out.print("show in B ; ");
System.out.println("a : " + a);
}
public static void main(String[] args) {
B p = new B();
p.show();
A q = new B();
q.show();
}
}
It's here
A q = new B();
q.show();
Compiler uses virtual call instructions (invokeVirtual or invokeInterface) for methods which can be overriden (they cannot be static or private). In this code JVM detects that A.show is virtual and checks the actual type of q. Since it is B it calls B.show. If it were static JVM would call A.show and we would see
show in A
I guess I confused you previously.
Dynamic (or late) binding is how polymorphism is implemented in Java. It occurs any time an instance method is invoked.
In your example, we are interested in the occurrences here
p.show();
and here
q.show();
At compilation time, the static type of the variable will be checked to see if the method show() is accessible, failing if it is not.
At runtime (dynamic), the run time (dynamic) type of the object will be checked to find an implementation of the method. If one is found, it is used, if not, the JVM keeps looking up the inheritance hierarchy.
For example
A q = new B();
q.show();
at run time, q is of type B and B overrides show() so B#show() is invoked.
In your answer I had commented on, the overriden method did not play a part. It was more a question of constructor execution order.
The method show() invoked in the below lines
A q = new B();
q.show();
The target object of the show method is determined at runtime.
you can change it in your main method to implement polymorphism or dynamic binding:
public static void main(String[] args) {
A a = new A();
a.show();
a = new B();
a.show();
}
as you can tell that even the reference is never changed A a but what it refer is changed, as different instance it point to, difference behavior will be done!
This is so called polymorphism.
Much powerful polymorphism, after using reflect in java will indulge you! have fun!
- Binding is act of method call identifying and calling its method body.
- Java only supports Dynamic Binding, except few exception cases.
- The compiler can't understand which method call to be associated with which method body... so its the responsibility of the method call to associated itself to its appropriate method body.
- Its very important to know that Fields (Instance Variables) are NOT POLYMORPHIC IN NATURE.
In your case the Dynamic binding is here:
A q = new B();
q.show();
Related
I have problems understanding the behaviour of this piece of code.
a is defined as an A, c is defined as a C.
Then, at the end of the public class, a = c.
When a calls the display() method it reaches the C version of it.
But when a calls the f() it only reaches the A version, despite the fact that the first arguments (byte and long) are more compliant with long than float.
It's an exercice from a book, but explanation is scarce, or inexistent.
class A{
public void display(){
System.out.println("I am an A ");
}
public void f(double x){
System.out.println("A.f(double = " + x + ") ");
}
}
class C extends A{
public void display(){
System.out.println("I am a C ");}
public void f(long q){
System.out.println("C.f(long = " + q + ") ");}
}
public class PolySurStack{
public static void main(String Args[]){
byte bb =1; long q = 4; float x = 5.f;
System.out.println(" ** A **");
A a = new A(); a.display();
a.f(bb); a.f(x);
System.out.println();
System.out.println(" ** C **");
C c = new C(); c.display();
c.f(bb); c.f(q); c.f(x);
System.out.println();
a = c; a.display();
a.f(bb); a.f(q); a.f(x);
}
}
When you call a.f(bb) or a.f(q) or a.f(x), the only method signatures the compiler can choose from are those defined in class A (or any super class of A), since a is a reference variable of type A.
Therefore, only public void f(double x) is considered. In order for public void f(long q) to be a candidate for overload resolution, you'd have to cast a to type C before calling f(), since only class C defines a method with that signature.
The important thing to understand is that method overloading resolution takes place in compile time. Only the compile time type of the reference variable for which you call the method determines which method signatures are candidates for method overloading resolution, as well as which candidate will be chosen.
I just found this on another forum :
Overloading :(same function name but different signature)
Two or more methods having the same name with different arugment in same class is known as Overloading.
Overloading is used when you want to extend the functionality.
Overloading is known as compile time polymorphism
Overriding :(same function name but same signature)
Two or more methods having the same method name and same arugment in parent class and child class in known as overriding.
Overriding is used when you want to reuse the existing functionlity.
Overriding is known as run time polymorphism
So the answer to my question seems to be that overriding resolution (like for display() )occurs at run time (here after a = c) while overloading resolution (like for f() ) occurs at compilation time, when a is Still an A.
I think.
I also found this page : https://beginnersbook.com/2013/04/runtime-compile-time-polymorphism/
to be clear and highly relevant to this topic.
The method selected by the compiler depends on the declared type, not on the runtime type.
The first series that declares as variable A can only invoke A methods (whatever the runtime type instantiated as A derives only of Object) :
A a = new A();
a.f(bb); a.f(x);
For the second series, the compiler binds the methods with the most specific parameter matching to the invocation since C is a A and so the compiler can bind any public methods of these here :
C c = new C();
c.f(bb); c.f(q); c.f(x);
But in the last chunk of code that probably questions yourself, a refers to C as runtime object but to A as declared type :
A a = new A();
// ...
a = c;
a.f(bb); a.f(q); a.f(x);
So only methods defined in A may be invoked.
I'll try to clarify the answer of #eran a bit so you can understand it.
A subclass has all the methods of its superclass, and then perhaps some more in addition to them. You have a variable of type A, in which you store an object of type C. C has all the methods that are defined in class A, and also an additional method that is f(long q). A is unaware of this new method, so since you store the object in a variable of A, you can't call f(long q).
You can however call display() because it is defined in A, but it will still be the C object that executes it.
say, I have the following code (it's a quiz question, so I can run it in my IDE but the logic how it's working is not quite clear to me):
public class Test {
public static void main(String[] args){
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
}
}
class A {
public static void doSth(){
System.out.println("Doing something in A");
}
}
class B extends A {
public static void doSth(){
System.out.println("Doing something in B");
}
}
class C extends B {
public static void doSth(){
System.out.println("Doing something in C");
}
}
The output will be the following:
Doing something in A
Doing something in A
Doing something in A
Thus, my first question is: what is the meaning of the declaration like
A aInstance2 = new B();
i.e., why to create an object of class B declaring it as an instance of class A? How the properties of aInstance2 as an object of class B change compared to the declaration
B aInstance2 = new B();
?
If I remove the word static from the declaration of the methods doSth() in the classes A, B, and C, the output changes to
Doing something in A
Doing something in B
Doing something in C
Thus, when the methods were static, the method doSth() of class A didn't get overridden by those of the subclasses and the output was always "Doing something in A" produced by the objects of different classes, whereas when it became an instance (non-static) method, it gets overridden (if I'm using the right term here). Why is it so?
Removing the word static you are doing Dynamic Binding , because you are pretty much saying : "Even though i know this object is of type A i want it to behave like a B ".
Adding the word static means you are making that method part of the class[Reference type] ,and each time you are calling :"A dosmth()" he knows it only applies to A so it shows the result of the mothod from the class A.
As to what would you do this?I for one learned about this feature from school and studied it even more when i decided to go to interviews becuase it;s one of the things that the interviewer wants to see if you can handle.
If you don't mind I will post a link with information about Static and Dynamic Binding
http://javarevisited.blogspot.ro/2012/03/what-is-static-and-dynamic-binding-in.html
Because static method is based on Reference type .
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
So internally it converts into :
A.doSth();
A.doSth();
A.doSth();
Static methods are class methods while non-static ones are instance methods. Therefore, when you call a static method over an instance you are actually calling it over the declared type of this instance. So, all below calls actually performs the same call: A.doSth() since all instances are declared as type A.
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
When you remove the static keyword, doSth() method becomes an instance method. Instance methods are performed over objects instead of classes. Moreover, when you re-declare an instance method in a subclass, this method is overriden by the subclass. In your example, class B and C override doSth(). Thus, each class provides its own implementation.
Overriding depends on having an instance of a class. A static method is not associated with any instance of a class so the concept is not applicable.
Making static methods works faster, because there's no need to wait until run-time to figure out which method to call.
Overriding in Java simply means that the particular method would be called based on the run time type of the object and not on the compile time type of it.
Illustration -
When doSth() is static:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
In the above code, the compiler will decide at compile time that without instance it should be called for A. No overriding.
When doSth() is not static:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
In the above code, the compiler will decide at run time that the method is not static and should be overridden by there respective instances.
static methods are at class level and act on the reference type(LHS of ==) unlike instance level methods which are dynamically dispatched based on the instance type(RHS of ==)
If I have two classes, A and B,
public class A {
public int test() {
return 1;
}
}
public class B extends A{
public int test() {
return 2;
}
}
If I do: A a1 = new B(), then a1.test() returns 2 instead of 1 as desired.
Is this just a quirk of Java, or is there some reason for this behavior?
This is called polymorphism. At runtime the correct method will be called according to the "real" type of a1, which is B in this case.
As wikipedia puts it nicely:
The primary usage of polymorphism in industry (object-oriented
programming theory) is the ability of objects belonging to different
types to respond to method, field, or property calls of the same name,
each one according to an appropriate type-specific behavior. The
programmer (and the program) does not have to know the exact type of
the object in advance, and so the exact behavior is determined at
run-time (this is called late binding or dynamic binding).
No, that is correct (it is due to polymorphism). All method calls operate on object, not reference type.
Here your object is of type B, so test method of class B will be called.
This is polymorphism and more specifically in Java overriding. If you want to invoke Class A's test method from Class B then you need to use super to invoke the super classes method. e.g:
public class B extends A{
public int test() {
return super.test();
}
This is intended behavior. The method test() in class B is overriding the method test() of class A.
For
A a1 = new B();
a1 is pointing towards the object of B which is the real type at run-time. Hence value is printed from Object B.
A obj = new A();
obj.test()
will return 1
A obj = new B();
obj.test()
will return 2
B obj = new B();
obj.test()
will return 2
As stated in other answers this is how polymorphism works.
This post may make things a bit clearer
Java uses dynamic binding (or late binding), so the method of B is called, not A. This is the opposite of static binding. There is a nice example here.
You declare your object as A but your instance is B. So the method which will be called is from class B. B extends A(we can say that A is parent for B) if you will comment method test in B and then recall this method, in this case the method invoked will be test from A class and will return 1.
I've been studying because I have an exam and I don't have many problems with most of Java but I stumbled upon a rule I can't explain. Here's a code fragment:
public class A {
public int method(Object o) {
return 1;
}
public int method(A a) {
return 2;
}
}
public class AX extends A {
public int method(A a) {
return 3;
}
public int method(AX ax) {
return 4;
}
}
public static void main(String[] args) {
Object o = new A();
A a1 = new A();
A a2 = new AX();
AX ax = new AX();
System.out.println(a1.method(o));
System.out.println(a2.method(a1));
System.out.println(a2.method(o));
System.out.println(a2.method(ax));
}
This returns:
1
3
1
3
While I would expect it to return:
1
3
1
4
Why is it that the type of a2 determines which method is called in AX?
I've been reading on overloading rules and inheritance but this seems obscure enough that I haven't been able to find the exact rule. Any help would be greatly appreciated.
The behavior of these method calls is dictated and described by the Java Language Specification (reference section 8.4.9).
When a method is invoked (§15.12), the number of actual arguments (and
any explicit type arguments) and the compile-time types of the
arguments are used, at compile time, to determine the signature of the
method that will be invoked (§15.12.2). If the method that is to be
invoked is an instance method, the actual method to be invoked will be
determined at run time, using dynamic method lookup (§15.12.4).
In your example, the Java compiler determines the closest match on the compile type of the instance you are invoking your method on. In this case:
A.method(AX)
The closest method is from type A, with signature A.method(A). At runtime, dynamic dispatch is performed on the actual type of A (which is an instance of AX), and hence this is the method that is actually called:
AX.method(A)
I will clarified it in more simple way. See when you making sub class object with super class reference like here you did.
Always one thing keep in your mind that when you call with super class reference, no matters object is of sub class it will go to the super class, check method with this name along with proper signature is there or not.
now if it will find it, than it will check whether it is overridden?? if yes than it will go to the sub class method like here it went. another wise it will execute the same super class method.
I can give you the example of it...just hide
public int method(A a) {
return 3;
}
method & check your answer you will get 1 2 1 2, why because it gives first priority to reference. because you overridden it & than calling it, so its giving 3..!! hope its big but easy to understand. Happy Learning
a2 referenced as an A and the JVM using the reference first (not the acutal object as you expected).
I have two classes A and B while B is a subtype of A:
public class A {
private String stringVar;
public A() {
stringVar = "";
}
public String getStringVar() {
return stringVar;
}
public void setStringVar(String str) {
this.stringVar = str;
}
#Override
public String toString() {
return getStringVar();
}
}
Class B:
public class B extends A {
private int intVar;
public B() {
intVar = 0;
}
public int getIntVar() {
return intVar;
}
public void setIntVar(int intVar) {
this.intVar = intVar;
}
#Override
public String toString() {
return super.toString() + " " + getIntVar();
}
}
As you can see in the following main method I assign the b to a. Now "a" can't invoke b's methods which is clear, because I'm using an instance of type A now. But it behaves like a B when toString is invoked. Curious, I would have expected toString of a. Why is this so?
public class Main {
public static void main(String[] args) {
A a = new A();
B b = new B();
b.setIntVar(200);
b.setStringVar("foo");
a = b;
System.out.println(a);
}
}
Because a points to the implementation of B.
And is declared as A.
So behavior of B. And methods visible of A.
To use B methods do like this
((B) a).getIntVar();
Think of it like this
Object o = new FancyObject();
When compiling this only Objects methods will be accepted even though it's a FancyObjcet with lots of methods.
To use the methods of FancyObject on o do like this.
Object o = new FancyObject();
(FancyObject o).fancyMethod();
Quote "because I'm using an instance of type A now" you are still using an instance of type B. You can see it like you have upcasted b but it's the same instance.
Picture cross linked from another site with credits in the picture, if this is against the rules then somebody is free to edit this part of my answer.
This is nature of inheritance / polymorphism and overriding methods.
Overrided methods will be determined in runtime based on objects real type and not based on reference type.
Therefore a.toString() is actually b.toString() because it is determined in runtime.
http://download.oracle.com/javase/tutorial/java/IandI/override.html
The concept you need to understand is the difference between References and Objects.
a is a reference (a local variable in this case) that points first to an Object of type A and then to an Object of type B.
The compiler knows that it must be of type A (or a subtype thereof), so it can safely call all methods A defines, but they will be called on the actual Object, not on the original Type of a.
This is polymorphism: The object that a holds has static type A, but it is still an Object of dynamic type B. Dynamic dispatch therefore chooses the overridden toString() defined in B.
That's exactly how Java's runtime polymorphism works. All that matters is the actual type at runtime. What you have done is take a reference to an A and point it at an instance of B. You have changed the type of the thing that a points to.
Try
a = (A)b;
No, B Overrides the toString method of A, so if an object is an instance of B, when you call its toString method, you get whatever method that instance has. In general, if you have an object and call its methods, the method called is the one that is in the instance, not in the variable type. The only exception is static methods.
In C++, this is not the case. The method called is the one of the variable type, if one exists, unless you explicitly select the above described behavior by making a method virtual.
That is called runtime polymorphism in OOP.