why polymorphism doesn't matters when a method is overloaded? - java

i know that overloaded methods are determined at compile time based on the reference type which invokes the method while overrided methods is determined by the actual object type of the reference invoking he method, the question is why polymorphism only matters about overriding and not overloading?

The implementation mechanism that makes polymorphism in Java possible is the dynamic dispatch of a method based on the runtime type of its first argument (in a call a.method(b, c), a can be considered the first argument of the method). Java is therefore a single dispatch OOP language. The upshot is that all other arguments don't participate in this mechanism and their type is determined statically at compile time. So for example if you have
class MyObject {
public boolean equals(MyObject o) { ... }
}
and then
MyObject m1 = new MyObject();
Object o = new MyObject();
System.out.println(m1.equals(o));
can never print true since your method is not being called. The compiler saw a call MyObject.equals(Object) and compiled it as a call of the inherited method Object.equals(Object). The runtime method dispatch mechanism will only decide which overriding method equals(Object) to call.

polymorphism , as the name implies , is when a method "of the same form" manifests different behaviours under different contexts. The term "same form" means "same signature". That implies you cannot relate polymorphism with overloaded methods because they have "different forms" to begin with. Another way to think about it is - you need a type and a subtype to see polymorphism in action - overloaded methods again are defined in the context of a single class.

This is for technical reasons. Usually only the this pointer, as hidden first parameter of the method, is analyzed at runtime to determine the method to be called.
When other parameters, too, are analyzed it is called Multiple Dispatch. There are a few languages that support multiple dispatch natively.

You are confused on this.
Overloading refers to selecting one of the methods having the same name but different signature in the same class (not hierarchy).
Overriding is chose among methods of the same name depending on the runtime type among those inherited by parent classes.
If you have a base class and a derived class with a method of the same name and signature then this is overriding and at runtime the correct is determined.
For overloading the compiler picks the correct version of method to use, among the available in the same class.
No need to find a runtime type. Compiler can figure this out at compile time

Related

What is the difference between Binding and Dispatching in Java?

There are too many associated names: Early and Late Binding, Static and Dynamic Dispatch, Runtime vs. Compile-time Polymorphism, etc. that I don't understand the difference.
I found a clear explanation, but is it correct? I'll paraphrase JustinC:
Binding: is determining the type of a variable (object?). If it's done at compile time, its early binding. If it's done at run time, it's late binding.
Dispatch: is determining which method matches the method call. Static Dispatch is computing methods at compile time, whereas dynamic dispatch is doing it at run time.
Is Binding matching up primitive and reference variables with primitive values and objects respectively?
Edit: Please give me some clear reference material so I can read more about this.
I believe the confusion typically comes from how overloaded these terms are.
We program our programs in a high level language, and either a compiler or an interpreter must transform that into something a machine actually understands.
In coarse terms, you can picture a compiler transforming our method code into some form of machine code. If the compiler knew at that point exactly where in the memory that method would reside when we run our program later, then it could safely go and find every method invocation of this compiled method and replace it with a jump to this address where the compiled code resides, right?.
Well, materializing this relationship is what I understand as binding. This binding, though, could happen at different moments, for example at compile time, linking time, load time, or at run time depending on the design of the language.
The terms static and dynamic are generally used to refer to things bound before run time and at run time, respectively.
Later binding times are associated with greater flexibility, earlier binding times are associated with greater efficiency. Language designers have to balance these two aspects when they're creating a language.
Most object-oriented programming languages support subtype polymorphism. In these languages, virtual methods are bound at runtime depending on the dynamic type of the object at that point. In other words, virtual method invocations are dispatched to the appropriate implementation at runtime based on the dynamic type of the object implementation involved and not based solely on its static type reference.
So, in my opinion, you must first bind the method invocation to a specific implementation or execution address, and then you can dispatch an invocation to it.
I had answered a very similar question in the past in which I demonstrate with examples how this happens in Java.
I would also recommend reading the book Programming Language Pragmatics. It is a great reference to learn all this kind of stuff from a theoretical standpoint.
When you're looking for "low level" definitions, probably the only legitimate source is our old friend - the JLS. Though it does not give a clear definition in this case, the context in which it uses each term might be enough.
Dispatch
This term is indeed mentioned in procedures of determining which method to call.
15.12.2. Compile-Time Step 2: Determine Method Signature
The second step searches the type determined in the previous step for
member methods. This step uses the name of the method and the argument
expressions to locate methods that are both accessible and applicable,
that is, declarations that can be correctly invoked on the given
arguments.
There may be more than one such method, in which case the
most specific one is chosen. The descriptor (signature plus return
type) of the most specific method is the one used at run time to
perform the method dispatch. A method is applicable if it is
applicable by one of strict invocation
The elaboration on what is the "most specific" method is done in 15.12.2.5 Choosing the Most Specific Method.
As for "dynamic dispatch",
JLS 12.5. Creation of New Class Instances:
Unlike C++, the Java programming language does not specify altered
rules for method dispatch during the creation of a new class instance.
If methods are invoked that are overridden in subclasses in the object
being initialized, then these overriding methods are used, even before
the new object is completely initialized.
It includes
Example 12.5-2. Dynamic Dispatch During Instance Creation
class Super {
Super() {
printThree();
}
void printThree() {
System.out.println("three");
}
}
class Test extends Super {
int three = 3;
void printThree() {
System.out.println(three);
}
public static void main(String[] args) {
Test t = new Test();
t.printThree();
}
}
Output:
0
3
This happens because during the constructor call chain, Super's constructor calls printThree, but due to dynamic dispatch the method in Test is called, and that is before the field is initialized.
Binding
This term is used in contexts of class member access.
Example 15.11.1-1. Static Binding for Field Access demonstrates early and late bindings. I will summarize the examples given there for the lazy of us:
class S {
int x = 0;
int z() { return x; }
}
class T extends S {
int x = 1;
int z() { return x; }
}
public class Test1 {
public static void main(String[] args) {
S s = new T();
System.out.println("s.x=" + s.x);
System.out.println("s.x=" + s.z());
}
}
Output:
s.x=0
s.x=1
Showing that the field uses "early binding", while the instance method uses "late binding":
This lack of dynamic lookup for field accesses allows programs to be run efficiently with
straightforward implementations. The power of late binding and overriding is available, but
only when instance methods are used.
Binding is also used in regards to determining the type of a generic,
8. Classes
Classes may be generic (§8.1.2), that is, they may declare type variables whose bindings may differ among different instances of the class.
Meaning that if you create 2 instances of List<String>, the bindings of String in both instances are different from each other.
This also applies to raw types:
4.8. Raw Types
class Outer<T>{
T t;
class Inner {
T setOuterT(T t1) { t = t1; return t; }
}
}
The type of the member(s) of Inner depends on the type parameter of Outer. If Outer is raw, Inner must be treated as raw as well, as there is no valid binding for T.
Meaning that declaring Outer outer (this will generate a raw type warning) does not allow to determine the type of T (obviously - it wasn't defined in the declaration).
These are general terms, you can summarize it in this way: when some thing(method or object) is static/early it means that thing is configured in compile-time and there is no ambiguity in run time for example in the following code:
class A {
void methodX() {
System.out.print("i am A");
}
}
If we create an instance of A and call methodX(), nothing is ambitious and everythin is configured at compile time but if we have the following code
class B extends A {
void methodX() {
System.out.print("i am B");
}
}
....
A objX= new B();
objX.methodX();
Out put of method x is not known until runtime, so this method is dynamically binded/dispatched (we can use the term dispatched instead of bind for methods link).

Why method overloading is the best example of static binding in Java?

In java, I know that we have some differences between static binding and dynamic binding and method overloading is the best example of static binding but I don't know why it is the method overloading instead of the the method overriding?
Method overloading is determined at compile time. The compiler decides, based on the compile time type of the parameters passed to a method call, which method having the given name should be invoked. Hence the static binding.
Method overriding is determined by the runtime type of an object. At runtime, the method that gets executed can be a method of some sub-class that wasn't even written when the code that makes the call was compiled. Hence the dynamic binding.

How does java compiler choose correct methods and variables in inheritance

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.

Method Overriding of diffrent Return type to void

let's say we have this method
public class Animal {
public void eat() { }
}
and on another class that extends Animal has this method
public String eat(){}
is this considered as method overriding? because I've heard that you can use different return types in method overriding providing they have the same method arguments
This is neither overloading , nor overriding ! It is compilation error .
In Java it is possible to define two or more methods within the same class that share the same name, as long as their parameter declarations are different. When this is the case, the methods are said to be overloaded, and the process is referred to as method overloading.
Following are rules of method overriding in java which must be followed while overriding any method. private, static and final method can not be overridden.
1)Method signature must be same including return type, number of method parameters, type of parameters and order of parameters.
2)Overriding method can not throw higher Exception than original or overridden method. This rule only applies to checked Exception in Java, overridden method is free to throw any unchecked Exception.
3)Overriding method can not reduce accessibility of overridden method , means if original or overridden method is public than overriding method can not make it protected.
You can only change the return type to a subclass of the original return type.
All answers are correct from a technical point of view because Void is a class in Java that no other class can extend and when methods are overridden the return-type has to be a sub-type of the original type (parentReturnType.isAsignableFrom(overriddenReturnType)).
But from a practical point of view the question is still valid and it would have made sense to make an excuse for the special case void. The only value a variable of the type Void can hold is null. Further no variable can have the primitive type void. Finally you can not compile this code:
Void result = object.notify();
So in the end it would have made sense to specify Java differently when 1.5 was introduced and allow overriding void return types with any other type.
Therefore the only reasonable answer is IMHO it is not possible because Java was designed such that this is not allowed.
This not correct Code, as two methods with same name should return same value, only arguments can be differents
Overriding is having same method with same arguments in the subclass
Overloading having same method name with different argumens
The return type of a method is not part of that method's signature.
When you call eat() on the subclass, java looks at the signature you provided (eat with no parameters) and starts looking for a method with this signature, starting in the class of the instance type of the object you call it on (and searches through its ancestors if it fails to find it).
So, methods called on a subclass will always run the overridden methods (they're found first).
A critical 'point' of OO (specifically polymorphism) is that a subclass can be passed in where the superclass was expected.
If a method wants to call the superclass' eat() method and get a void, but you passed a subclass into that method of which eat() returned a String; you can see that method will call the subclass' eat and get an unexpected value.
You can see why this could be a problem. :I
So, overriding methods must return the same type or a subclass of the type returned by the parent.
(Similar principles apply as to why you can return a subclass; I'll let you think about it c: )
It's neither overriding nor overloading, it creates compilation error.
Two methods with same name, different param numbers or different type of params known as overload method, return type may be same or different. It may be in same class or parent, child classes.
Two methods having same param numbers, same types, same return types but one is in parent class and other is in child class are known as overrided methods.

Clarification on overloading

When the parent class have an add method with 2 parameters, If we add new add method with 3 parameters in child class, shall we call this as over loading?
Thanks in advance.
Yes, since the method with two parameters is inherited by the subclass, the method with three parameters is said to be an overloading method.
class A
add(param1, param2)
class B
add(param1, param2) <-- inherited
add(param1, param2, param3) <-- overloading the above method
A quote from the official trail on Overriding and Hiding Methods:
Note: In a subclass, you can overload the methods inherited from the superclass. Such overloaded methods neither hide nor override the superclass methods—they are new methods, unique to the subclass.
(As you probably already figured out, the method with three classes is not an overriding method.)
Yes, this is overloading. It would be overloading even if the method were in the same class as the method with two parameters.
Note that when there are different numbers of parameters (and no varargs parameters) overloading is reasonably simple. It gets a lot more complicated when you have methods with the same number of parameters - at that point the compiler has to choose the "best" method out of applicable candidate methods.
Also note that overloading is determined at compile time whereas which override is executed is determined at execution time based on the actual type of the object the method is called on.
Overloading is when methods have the SAME NAME but DIFFERENT SIGNATURE.
Overriding - when methods have IDENTICAL NAMES and IDENTICAL SIGNATURE.
Yes definitely a overloading and a nice feature of inheritance.
If the method name already exists but the parameters are different, then yes, this is overloading.
yep... it is overloading method even if the method is located in the same class.
ps: i assume the new method with three parameters has identical name and return type

Categories

Resources