POLYMORPHISM
One interface multiple methods. i.e one interface is used for different actions
There are two types of polymorphism:
1) Compile
time polymorphism – function overloading
2) runtime
polymorphism—dynamic linking
For example : if in a program we have 3
different types of stacks:
One which calculates int, double and other float..
One which calculates int, double and other float..
Then we can have a method named stack (same name) with different types of parameters.(different actions):
-->stack(int)
-->Stack(double)
--->Stack(float)
i.e same name but different type of arguments.
The compilers’s job is to select the right method, programmer
doesn't have to select it manually.
But how does Compiler know?? which method to select at compile time?
But how does Compiler know?? which method to select at compile time?
FUNCTION OVERLOAD RESOLUTION IN JAVA
Java's overload resolution
process operates in two phases.
The first phase: For a given function call, find the set of all applicable methods on the basis that there must exist either an exact match or a widening type conversion from each argument in the function call (i.e the actual parameters )to the corresponding parameter of the method being considered. If this set consists of only one method, select that method for invocation. Otherwise proceed to the next step. They are used only to determine which overloadings are applicable
The second phase: It selects the most specific of the methods or constructors selected in the first phase, it selects the most specific overloading, using only the formal parameters: the parameters appearing in the declaration . If there exists either an
1) exact match
2) widening type conversion
from each of the parameters of a method in the set to the corresponding parameters of another method, eliminate the latter method from the set.
If you are left with only one method after pruning the set in this manner, select that method for invocation. Otherwise proceed to the next step.
The third phase: Declare the source code invalid because there does not exist a single maximally specific method that can be invoked for the function call.
1) exact match
2) widening type conversion
from each of the parameters of a method in the set to the corresponding parameters of another method, eliminate the latter method from the set.
If you are left with only one method after pruning the set in this manner, select that method for invocation. Otherwise proceed to the next step.
The third phase: Declare the source code invalid because there does not exist a single maximally specific method that can be invoked for the function call.
Consider the following example:
//Overload.Java
class Employee {String
name;}
class Manager extends
Employee {int level;}
class Test {
static void foo(Employee e1, Employee e2) { //first foo //(A)
System.out.println( "first
foo");
}
static void foo(Employee e, Manager m) { //second foo
//(B)
System.out.println( "second
foo");
}
static void foo(Manager m, Employee e)
{ //third foo //(C)
System.out.println( "third
foo");
public static void main(String[] args)
{
Employee emp = new Employee ();
Manager man = new Manager();
foo(emp,
man); // will invoke the second foo
//(D)
//foo(man,
man); // Error because it produces an
//(E)
// ambiguity in
overload resolution
}
}
When we call ---à foo(emp,man)
Phase 1:
Find set of applicable methods, i.e exact match and widened type conversion, also here actual parameters are considered, i.e parameters called during invocation :
Find set of applicable methods, i.e exact match and widened type conversion, also here actual parameters are considered, i.e parameters called during invocation :
A)
foo(Employee e1, Employee e2)-à foo(emp,man)
emp is exact
match, man is an employee object( widened type ,comparing
with actual parameters)à so pass
B)
foo(Employee e, Manager m) à foo(emp, man)
emp is exact match, man is an exact match with
man-à so pass
C)
foo(Manager m, Employee e)à foo(emp,man)
emp object is not always a manager object—not pass (taking formal parameters into
consideration)
every manager object is an employee object..
So end of Phase 1: {A, B}
Phase 2: {A, B}
A--> has one exact match and other widened match
B--> have both exact match
So, eliminate the one who has widened match, in our case A
Hence, B--> foo (Employee e, Manager m) would be called
A--> has one exact match and other widened match
B--> have both exact match
So, eliminate the one who has widened match, in our case A
Hence, B--> foo (Employee e, Manager m) would be called
Now consider that happens if we uncomment the call to foo in line (E). Its
argument types match the parameter types for all three definitions of foo. So at the end of the
first step of overload resolution, we have three candidates in the set.
By the same reasoning as before, we now discover that the first definition of foo is less specific than the other two. So we delete it from the set. However, we also discover that it is not possible to delete either of the remaining two entries from the set, for the simple reason that an Employee type does not possess a widening type conversion to a Manager type. So we declare ambiguity and, therefore, compile time error results.
By the same reasoning as before, we now discover that the first definition of foo is less specific than the other two. So we delete it from the set. However, we also discover that it is not possible to delete either of the remaining two entries from the set, for the simple reason that an Employee type does not possess a widening type conversion to a Manager type. So we declare ambiguity and, therefore, compile time error results.
If you have many types and
this is unmanageable, then method overloading is probably not the right
approach, rather the public method should just take Object and implement some
kind of strategy pattern to delegate the appropriate handling per object type.
Ability to dispatch a call
to a method based on types of arguments is called multiple
dispatch. In Java this is done with Visitor
pattern..
References: