Suppose I have class A
public class A
{
public void method()
{
//do stuff
}
}
Also another class B
public class B extends A
{
public void method()
{
//do other stuff
}
}
Now I have the following statements:
A a = new B();
a.method();
Is this an example of run time polymorphism? If yes, then is no binding is done for the reference a at compile time?
The compiler will tell you that this can't work, because there's no relationship between A and B that will allow you to write A a = new B();
B either has to extend A or both have to implement a common interface with void method() in it.
You could have answered this very quickly by trying it with the compiler. Be an experimentalist - it's faster than forums.
UPDATE:
It works, now that B extends A. The binding that you care about, dynamic binding, is done at runtime. The static compile time type for the variable "a" is class A; at runtime it is dynamically bound to a reference of type B. Yes, I would consider this to be an example of polymorphism.
I was waiting to put my answer to another post, into a more correctly classified problem. Your question fits the concept, I've tried to explain in detail. but, since I don't know how link answers, I'll just copy/paste the complete script here .... Kindly go through it, you'll understand everything that there is to understand about your problem, you've asked
let's say compiler has to resolve a call like this : *
A a = new AA(); // Assume AA to be some subclass of class A
a->someFunc(); // and we're invoking a method "someFunc()' on a
*.
Now, compiler will go over following steps methodically.
1.) Firstly, compiler knows the declared type of variable a, so it will check whether the declared type of object a (lets call this, class A for time being), have a method with the name someFunc() and that it must be public. This method could either be declared in class A, or it could be a derived method from one of the base class(es) of class A, but it doesn't matter to compiler and it just checks for it's existence with it's access specifier being public.
Needless to say any error in this step will invite a compiler error.
2.) Secondly, once the method is validated to be a part of the class A, compiler has to resolve the call to the correct method, since many methods could be there with same name (thanks to function overloading). This process of resolving correct method is called overloading resolution. Compiler achieves this by matching the signatures of the called method with all the overloaded methods that are part of the class. So, of all the someFunc() s only the correct someFunc() (matching the signatures with called method) will be found and considered further.
3.) Now comes the difficult part, It may very well happen that someFunc() may have been overridden in one of the subclasses of the class A (lets call this class AA and needless to say it is some subclass of A), and that variable a (declared to be of type A) may actually be referring to an object of class AA, (this is permissible in C++ to enable polymorphism). Now, if the someFunc() method is declared to be of type virtual, in base class (i.e. Class A) and someFunc() has been overriden by subclass(es) of A (either in AA or classes between A and AA), the correct version of someFunc() have to be found out by the compiler.
Now, imagine you're the compiler and you have this task of finding whether the class AA has this method. Obviously, class AA will have this method since, it is a subclass of A and public access of A in class A has already been validated in Step 1 by the compiler !!! . But Alternatively, as mentioned in previous paragraph, someFunc() may be overriden by class AA (or any other class between A and AA), which is what compiler needs to catch. Therefore, you (since, your'e playing the compiler) could do a systematic check to find the bottom-most (lowest in the inheritance tree) overridden method someFunc() starting from class A and ending at class AA. In this search, you'll look for same method signatures as was validated in overloading resolution. This method will be the method which will be invoked.
Now, you may be wondering, "What the heck", is this search done everytime ? ... Well, Not really. The compiler knows the overhead of finding this everytime, and as such, maintains a data-structure called Virtual Table for every class type. Think of virtual table, as mapping from method signatures (which are publicly accessible) to the function pointers. This virtual table is made by compiler during compilation process and is maintained in-memory during program execution. In our example, class A and class AA will both have their own virtual tables. And when compiler has to be find someFunc() in class AA (since actual object pointed by variable a is of type AA), it will simply find the function pointer through the virtual table of Class AA. This is as simple has hashing into the table and is a constant time operation.
Regards
AViD
The code example you've given isn't legal, so I guess the answer is that it's not a kind of polymorphism.
You can't assign a class to a variable of an unrelated type like that. I'm guessing that you might be intending for B to derive from A?
Is this an example of run time polymorphism?
As of the edit: yes that would be runtime polymorphism, since which method is actually executed depends on what is assigned to a.
Edit:
If method() would be static, then calling a.method() would always result in the version of A being called. However, you'd then just write A.method() and if you don't do that any decent IDE would warn you about that (because it might be misleading to call a static method on an instance).
End Edit.
Compile time polymorphism would be the overloading mechanism, i.e. the compiler decides whether to use someMethod(Number) or someMethod(Integer) depending on what it knows about the parameter that is passed (if you pass a Double or just a Number it would be the first one, if you pass an Integer it would be the second).
If yes, then is no binding is done for the reference a at compile time?
What do you mean exactly? Note that the type of a will be A so you can assign everything that extends A at runtime. The compiler will just complain if the assigned value is not an A (you might trick the compiler with a cast, but this is just evil and if this breaks your program, you have been warned ;) )
It should be
public class B extends A {
public void method()
{
//do other stuff
} }
If it were compiling, it would be the B::method() that would be called. (only if you changed your code to make the B class inherit the A class).
In this case your use your object like it was only an A, but if some methods are overidden in B, then these methods are called, instead of A's methods.
Related
This question already has answers here:
Why is it that we cannot override static and final methods? [duplicate]
(5 answers)
Closed 1 year ago.
In Java, what is the actual reason behind the inability to write a method in a sub class which has the same name as a final method in the super class? (Please note that I am not trying to override the method, this is why I have put the keyword final.)
Please see the example below:
class A {
public final void method() {
System.out.println("in method A");
}
}
class B extends A {
public void method() {
System.out.println("in method B");
}
}
The problem is expressed as "'method()' cannot override 'method()' in 'A'; overridden method is final" in the IDE; however, I would like to understand what it is about this situation that leads the compiler to fail.
Because in java, overriding isn't optional.
Names of methods at the class level.
At the class level (as in, what is in a class file, and what a JVM executes), method names include their return type and their parameter types (and, of course, the name). At the JVM level, varargs doesn't exist (it's an array instead), generics do not exist (they are erased for the purposes of signature), and the throws clause isn't a part of the story. But other than that, this method:
public void foo(String foo, int bar, boolean[] baz, long... args) throws Exception {}
turns into this name at the class file level:
foo(Ljava/lang/String;I[Z[J)V
which seems like gobbledygook, but [ is 'array of', the primitives get one letter each (Z for boolean, J for longs, I for integer), V is for void, and L is for: Object type. Now it makes sense.
That really is the method name at the class level, effectively (well, we call this its signature). ANY invocation of a method in java, at the class level, always uses the complete signature. This means javac simply cannot compile a method call unless it actually knows the exact method you're invoking, which is why javac doesn't work unless you have the full classpath of everything you're calling available as you compile.
Overriding isn't optional!
At the class level, if you define a method whose full signature matches, exactly, a signature in your parent class, then it is overriding that method. Period. You can't not. #Override as an annotation doesn't affect this in the slightest (That annotation merely causes the compiler to complain if you aren't overriding anything, it's compiler-checked documentation, that's all it is).
javac goes even further
As a language thing, javac will make bridges if you want to tighten the return type. Given:
class Parent {
Object foo() { return null; }
}
class Child extends Parent {
String foo() { return null; }
}
Then at the class level, the full signature of the one method in Parent is foo()Ljava/lang/Object; whereas the one in Child has foo()Ljava/lang/String; and thus these aren't the same method and Child's foo would appear not to be overriding Parent's foo.
But javac intervenes, and DOES make these override. It does this by actually making 2 methods in Child. You can see this in action! Write the above, compile it, and run javap -c -v on Child and you see these. javac makes 2 methods: Both foo()Ljava/lang/String; and foo()Ljava/lang/Object; (which does have the same signature and thus overrides, by definition, Parent's implementation). That second one is implemented as just calling the 'real' foo (the one returning string), and gets the synthetic flag.
Final is what it is
Which finally gets to your problem: Given that final says: I cannot be overridden, then, that's it. You've made 2 mutually exclusive rules now:
Parent's foo cannot be overriden
Child's foo, by definition (because its signatures match), overrides Parent's foo
Javac will just end it there, toss an error in your face, and call it a day. If you imagined some hypothetical javac update where this combination of factors ought to result in javac making a separate method: But, how? At the class level, same signature == same method (it's an override), so what do you propose? That java add a 0 to the end of the name?
If that's the plan, how should javac deal with this:
Parent p = new Child();
p.foo();
Which foo is intended there? foo()Ljava/lang/Object; from Parent, or foo0()L/java/Object; from child?
You can write a spec that gives an answer to this question (presumably, here it's obvious: Parent's foo; had you written Child c = new Child(); c.foo(); then foo0 was intended, but that makes the language quite complicated, and for what purpose?
The java language designers did not think this is a useful exercise and therefore didn't add this complication to the language. I'm pretty sure that was clearly the right call, but your opinion may of course be different.
Final means not just that you can’t override it, it means you can’t work around having that method get called.
When you subclass the object, if you could make a method that shadows that final method, then you could prevent the superclass method from functioning, or substitute some other functionality than what the user of the object would expect. This would allow introducing malicious code and would defeat the purpose of making methods final.
In your case it sounds like making the superclass method final may not have been the best choice.
I was reading up on Polymorphism and after some searching I was confused about about the difference of compile-time and run-time polymorphism.
Lets say i have a class ABC and one other class that extends ABC,
class DEF like so:
class ABC{
public void myMethod(){
System.out.println("Overridden Method");
}
}
public class DEF extends ABC{
public void myMethod(){
System.out.println("Overriding Method");
}
}
public static void main(String args[]){
ABC obj = new DEF();
obj.myMethod();
}
}
If we want to be able to replace a class with another class, which performs the same task but in a different way without having too recompile the class that calls them, Is method overriding the way or method overloading?
I guess you are asking two things
1) I was reading up on Polymorphism and after some searching I was
confused about about the difference of compile-time and run-time
polymorphism.
Let's separate the waters here a little bit...
At compile time the compilator validates and transform the code into bytecodes. The static methods calls are resolved during this phase so you know every time the static method is invoked the same and sole implementation will take place.
run-time polymorphism is what happen at execution to decide what actual implementation of a given method to chosse. Considering that each class in the hierchary provides one implementation of this "polymorphic" method. Behind the curtains the compiler do a lot of work to archieve this, using something known as late binding mechanism.
2) If we want to be able to replace a class with another class, which
performs the same task but in a different way without having to
recompile the class that calls them, Is method overriding the way or
method overloading?
You don't actually say that replaces, inteads talks about extends, that is the thing that your are doing when a class extends another. And the implementations of the a method in parent class can be overwritten in a subclass.
Overload, has nothing to do with hierarchies, is to write the same method with diferents set of parameters.
Overloading is when you create multiple classes with the same method name, but different params. If a subclass has the exact same method name and params, it really ends up being overwriting, whether your put #overwrite on top or not. It´s literally the same exact thing and either way you change the outcome of the method, even if you use the base/super - class as a type.
This could be helpful When do you use Java's #Override annotation and why?
You´ll make your compiler complain that you are not actually overwriting a function if you mistype one of the two and nothing ends up being overwritten and you´ll make your code easier to read. It won´t affect the outcome, but you still should use it for those reasons.
I am a bit confused when inheritance and type casting is mixed. I want to understand the rules which java compiler follows when choosing correct methods and variables in inheritance.
I have read something like
Variables are bound at compile time and methods are bound at run time.
The second one is from stackoverflow (#John Skeet)
Overload resolution (which method signature is called) is determined at compile-time, based on the compile-time types of both the method target and the argument expressions
The implementation of that method signature (overriding) is based on the actual type of the target object at execution time.
But the problem is that they are explanations of specific situations and do not give the general process to be followed when other factors (like exception handling) are taken into consideration.
This may be bad practice but assume that both methods and variables are overridden(hidden in case of static variables).
Now if java compiler has to choose at compile time which method/variable needs to be invoked then what algorithm will it follow? Similarly at run time what is the algorithm that java compiler will use(based on the actual type of the object whose reference is being used)?
All method signatures and variables are verified during compile-time but the actual method calls are done / resolved during run-time.
For example :
class A {
int i=5;
public void doSomething(){
//print "in A"
}
}
class B extends A{
int i=10;
public void doSomething(){
// print "in B"
}
public static void main(String[] args){
A a = new B();
a.doSomething();
}
}
Now, when you call a.doSomething(); , during compilation, the compiler just checks whether doSomething() is defined for class A (lhs reference). It is not even bothered about whether the method is also defined for class B. Even if the method were not present in B, the program would compile fine.
Next, during runtime, the JVM dynamically decides which method to call based on type of Object (B in your case.).
So, "in B" is printed.
Now, coming back to fields. Access to fields are resolved during compile time. So, if a field doesn't exist during compile-time, then the compilation fails. The fields are called based on the reference type. So, a.i will print 5 (A's value of i) because the field was resolved during compile-time. Thus, the difference is, method calls are resolved during runtime, their signatures are needed / checked during compile-time where-as fields are checked / resolved during compile-time.
I have searched through all the similar questions on late binding on stack overflow, and I would severely disagree with anyone who marks this question as a duplicate. First off, i found this example on another question, but I do not understand how I am supposed to know when something is decided during compile time and when something is decided during run time. Basically, the crux of my question boils down to two things:
What in this example must bring me to the logical conclusion that one method is late binding and another is early binding
How do I know when the decision about which version of a method to execute is decided during run-time or compile time in Java
Code:
class A
{
public void foo()
{
System.out.println("Class A");
}
}
class B extends A
{
public void foo()
{
System.out.println("Class B");
}
}
public class C
{
public static void main(String [] args)
{
A a=new A();
B b=new B();
A ref=null;
/*
early binding --- calls method foo() of class A and
decided at compile time
*/
a.foo();
/* early binding --- calls method foo() of class B and
decided at compile time
*/
b.foo();
/* late binding --- --- calls method foo() of class B and
decided at Run time
*/
ref=b;
ref.foo(); }
}
Wrong on all counts. The method to be called is decided at runtime, in every case here, based on the runtime type of the object. The only decisions made at compile time are for calls to final, private, or static methods, or choices among a set of overloaded methods (which could still lead to runtime choices if the overloaded methods are not final, private, or static.)
Java uses late binding for all non-final, non-private instance methods. This is how polymorphism is implemented. All of the calls you commented on are determined at run time.
In
A a=new A();
a.foo();
a is referencing an A object so A's implementation will be found, bound and used.
In
B b=new B();
b.foo();
b is referencing a B object so B's implementation will be found, bound, and used.
In
ref=b;
ref.foo();
ref is referencing a B object so B's implementation will be found, bound, and used.
The static (declared) type of the variable is only used by the compiler to verify that such a method is accessible on that type.
Related:
What is early and late binding?
All the answers here are mostly correct, but there is one key point missing regarding late binding in Java.
Java does not perform "by the book" late binding if we go by the definition of late binding.
Late binding in its book definition form means that the compiler should perform no argument checks, no type checks on a method call and should leave it all to the runtime - because possibly the compiler does not have access to the method implementation code (for example in COM programming).
Java however at compile time does verify, even in a polymorphic scenario, that the method being called and the method signature does exist somewhere in the type hierarchy of the expression that qualifies the method. So for example, lets say I call a method foo1 on ref that does not exist in either A or B:
A ref=null;
ref=new B();
ref.foo1();
//This will not compile in Java, because java will check at compile time
//for the method foo1 in the type hierarchy of A, which is the type of the
// variable ref at compile time.
//In pure late binding, however this would pass compilation and
//throw an error at runtime.
In a pure late binding scenario, the determination of whether the method foo1() exists or not with the right number of arguments is made purely at runtime.
However in Java, there is some level of checking done at compile time, to ensure that the method with the right number of arguments does exist somewhere in the type hierarchy.
The only time that I think Java does perform pure late binding is if one uses reflection to call a method.
What Java does is better termed as dynamic dispatch rather than late binding, but everyone calls it late binding in Java and hence there is confusion.
Consider the statement
A ref; //reference of A
ref = new B();//Object of B
ref.f2();
Here ref is a reference of class A and it has address of object of class B f2() is a overridden method.
When compiler detects such a statement then it doesn't bind the function call with any definition. It only validates the call.
Binding of such calls is left for the runtime environment. At program runtime system identifies the datatype of the object and binds the function call with the function definition provided by the class of object. This type of binding between the function call and function defination is called as "late binding" or "runtime binding" or "runtime polymorphism" or "dynamic method dispatch".
go through this question and read my answer example is also given there.
When you call a method on any object, always remember in inheritance "least modified version" of method will be called. This is nothing but dynamically picking the method version from the hierarchy.
I suspect it is the type of the class in which it is written but I am not 100% sure, could someone please confirm my suspicion and perhaps give a reference to Java Language Specification where this behaviour is defined?
Let's say class A has a method a() which uses the this keyword in its body, and class B extends class A. Now class B has inherited method a(), however, I am not sure if the compile time type of this in B.a() is now A or B ?
I am asking this because I am trying to understand how the visitor pattern works, as it is described in this Robert C. Martin's Visitor chapter from The Principles, Patterns, and Practices of Agile Software Development.
It seems to be crucial to know the compile time type of this if one wants to fully understand the visitor pattern because overloaded method calls are resolved at compile time. More specifically, I refer to the compile time type of this in the accept methods in the visitor pattern.
The type of this is the type of the class in which it is used. In fact, it is crucial for the visitor pattern from the article to work.
Visitor pattern implements double dispatch in two steps - selecting the appropriate accept method in the object being visited (first leg), and then selecting the appropriate visit method in the visitor (second leg). The first leg is implemented through overriding; the second leg is implemented through overloading.
Note that it is not necessary to use overloading for the second leg. In fact, it is common not to use it there for better readability. Compare these two implementations:
// Copied from Listing 29-2
public interface ModemVisitorOverload
{
void visit(HayesModem modem);
void visit(ZoomModem modem);
void visit(ErnieModem modem);
}
public interface ModemVisitorNoOverload
{
void visitHayes(HayesModem modem);
void visitZoom(ZoomModem modem);
void visitErnie(ErnieModem modem);
}
The second implementation is not using the overloading. It works in exactly the same way, except human readers of the code immediately see what is going on.
this is a reference to the current object and as the JLS 15.8.3 states
The type of this is the class C within which the keyword this occurs.
At run time, the class of the actual object referred to may be the class C or any subclass of C.
Thank you for the answers.
After reading the answers I got inspired to try to compile the code below. The result of this little experiment might give also some insight into the answer to the original question.
The code below does not compile because this in A is not the correct type (according to the compiler). So for the visitor pattern to work the accept method needs to be repeated in subclasses of A and the methods called by v.visit(this) are fixed already at compile time (as others have pointed out already in their answers).
The point of the original question was whether one could avoid this redundancy in code but it seems not.
class A{
void a(VisitorI v){v.visit(this);}
}
class B1 extends A{}
class B2 extends A{}
interface VisitorI{
void visit(B1 b1);
void visit(B2 b2);
}
class Visitor implements VisitorI{
public void visit(B1 b1){
System.out.print("b1");
}
public void visit(B2 b2){
System.out.print("b2");
}
}
There's no such thing as B.a. There is only one method here and that is in class A, so this obviously has the static type of A. This isn't C++ where function bodies get duplicated willy nilly (if you use templates).
Now if you created a method named a inside of class B, then this would have the static type of B inside that method. And thanks to the magic of virtual methods, it would get called based on the runtime type when you invoke .a() on an object that could be either type A or B. But this is onyl if you override A's method.
An instance of an Object can only have one type. In the case of an instance of B extends A then this will always be a B, even inside methods of A.
However you can always use an object of type B as thought it is an an object of type A so even though getClass will return a B all the methods within A can use this as though it were a A.
For example its completely valid to do:
A a = new B(); // Valid as B extends A
a.test();
If B declares a method test() then that version of the method will be called, even though you are referring to it as though it were an A.
This is also how things like over-riding methods can be used to change the behavior of a base class from a sub class. When you have a method test() in A, and then override the method in B then whenever code in A calls this.test() it will actually call the over-ridden method in B.
Your mistake comes from the assumption that Overriding is resolved at compile time. It's not, it's resolved at run time Over load ed methods are resolved at compile time. Over ride n methods are resolved at run time. Overloading and Overriding are very different things.