I refer to some java tutorials and found java having two types of polymorphism.
compile-time polymorphism(Static polymorphism)
runtime polymorphism(Dynamic polymorphism)
some learning references are mentioned "If you overload a static method in Java, it is the example of compile-time polymorphism". and some are mentioned "Method overloading is an example of compile-time polymorphism".
what I want to know is if only static method overloading or every method overloading is the java compile-time polymorphism.?
Because when reading the first point I'm feeling why static method specially mentioned and why not instance methods and constructors are not mentioned.
Thanks
In Java, the choice, which of the overloads to invoke, is always made at compile-time. This applies to static methods, instance methods, and also constructors.
Note that the two statements are not contradicting. The first says, “If you overload a static method…”, which names a correct example, but doesn’t preclude other examples. Likewise, the other statement “Method overloading is an example of compile time polymorphism” is broader, still correct, while not mentioning constructors. As long as these statements do not claim to have named all existing examples, they are correct.
Still, in case of instance methods the chosen overload can also be subject to runtime polymorphism when being overridden, in addition to the compile-time polymorphism. Having methods which are both, overloaded and overridden, can easily lead to errors, therefore should be used with care or avoided.
Related
I'm learning Java and I have a question.
We can overload a method in various ways and the program executes just one. So the program has to determine which function to use.
My question is, who selects the function? Is it java compiler, or JVM?
Another name to Method Overload is "compile-time polymorphism". At compile-time, java knows which method to call by checking the method signatures. So this is called compile-time polymorphism or static or early binding.
There are two types of polymorphisms. Another kind of polymorphism named as "run-time polymorphism". This is achieved by Method Overriding (parent/child relationship in classes). Object is bound with the functionality at run time. Java virtual machine determines the proper method to call at the runtime, not at the compile time.
Method overloading is handled by the java compiler at compile time based on arguments. Here's an example for method overloading:
class Main{
void func(){System.out.println("No Params");}
void func(int a){System.out.println("Has Params");}
}
Here's a link where you can learn more about it in detail: https://www.infoworld.com/article/3268983/java-challengers-1-method-overloading-in-the-jvm.html
Before I ask my question, let me to explain my understanding and opinion.
By only Overriding we can't achieve polymorphism unless there is upcasting. And as it can only seen at runtime people might have named it as Run time ploymorphism. (I have no objection to call polymorphism as Run Time Polymorphism)
I have objection to call method overloading as compile time polymorphism or polymorphism.
I agree that method overloading is static binding (compile time binding), but I can't see polymorphism in that.
According to the javadoc, there is only polymorphism. There is no compile time or run time polymorphism.
According to javadoc in a section called Defining Methods, it explains Overloading of Methods. But there is nothing about compile time polymorphism.
According to me:
If you put polymorphism in to category of Run time polymorphism, you can only see "compile time polymorphism" when you change your JDK version:
If you switch from a higher JDK version higher to a lower one, you will start seeing compilation errors. The same code behaving differently during compilation time, eg: lambda expression, diamond operator, string in switch case, generics etc.
Let me elaborate my opinion, my prediction about how run time polymorphism and compile time polymorphism came to blogs/tutorials:
Conversation1
Developer 1: Hey I read about polymorphism today. If you do coding to interface, you can achieve polymorphism. writing codes not tightly coupling to a class but instead writing it to interface by making loose coupling, calling a superclass method or interface method actually invokes method of subclass depending on instance passed.
Developer 2: Sorry, I didn't get you.
Developer 1: It's simple at run time which object instance you will pass, that instance method will be executed.
Developer 2: Ohh! Run Time. I got it.
Developer 1: Yes same piece of code, but at Run Time passed instances are different.
Developer 2: **Run Time! Okay, I got it.
Conversation2
Developer 2: Hey yesterday I've met Developer1, he was telling about some run-time polymorphism. By overriding methods in a sub-class we can achieve it.
Developer 3: Run time polymorphism by overriding methods? Then what is oveloading? Compile time polymorphism?
Developer 2: How do you say overloading as compile time polymorphism?
Developer 3: Because it is decided at compile time only.
Developer 2: Silent!
Polymorphism and coding to interface best example is java.sql:
java.sql.Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);
java.sql.Statement stmt = conn.createStatement();
java.sql.ResultSet rs = stmt.executeQuery(sql);
The same piece of code behaves differently based on the Driver registered. This means, if we register the Mysql driver, due to polymorphism this code executes methods of mysql instances. I.e. it executes overridden methods. If you register the Oracle driver, it works for Oracle, and so on.
Above we found same code behaving differently.
Now can anyone show me same code behaving differently in compile time. Or in other words show me add(3,4) method bounded to different methods (other signatured methods) during compile time?
According to javadoc,
The Java programming language supports overloading methods, and Java can distinguish between methods with different method signatures.
The method will be executed depending on signature matched. Having same name for methods does not mean there is a polymorphism, because calling methods signature is different:
Queestion1: If you won't change calling method signature will it call different method other than method for which signature has matched? In any condition will it behave differently?
Let's look at Method overloading:
public void add(int a, int b)
{
System.out.println(a+b);
}
public void add(int a, int b, int c)
{
System.out.println(a+b+c);
}
public static void main(String[] args)
{
add(3,4);
add(3,4,5);
}
Question 1: If method overloading is polymorphism, Which piece of code behaving differently in above block of code? Where is polymorphism here?
Question 2: Method invocation add(3,4); on what scenario it shows ploymorphism, unless it is modified to add(3,4,5)?
EDIT
#FutureVisitor since this thread found no answers in favor of method overloading as a type of polymorphism(Even after a month of question being asked), without any justification accepting answer in favor of Method overloading is not a polymorphism, if any answer points problem in my argument of method overloading is not polymorphism will be accepted and supported their views.
In the Java world, polymorphism means polymorphism between classes. I.e. refering possibly multiple child classes with their common parent. In Java, there is no polymorphism between methods.
void add(int a, int b) and void add(int a, int b, int c) are entirely different methods in the Java syntax. It shouldn't be so - for example, in C++, you can cast them to each other -, but it is so in Java.
The key concept to understand here is the method signature. The method signature defines in a language, what identifies the induvidual methods. (For example, beside a void add(int a, int b);, you simply can't declare an int add(int a, int b); method - the return value is not a part of the method signature in Java, thus the compiler would interpret it as a method re-definition.)
People say
overriding is run time polymorphism and
overloading is compile time polymorphism.
Both are wrong.
Only Overriding is not polymorphism. But overriding helps to achieve polymorphism. If there is no upcasting you can't achieve polymorphism.
Overloading is a concept where method-name along with argument signature is used to bind method call to method body and it can be predicted during compile time only. But this is nowhere related to polymorphism. There is NO behavioral change that can be found in the case of method overloading. Either you compile today or compile after one year behavioral change can only be found if you change calling method signature i.e, only if you modify code to say add(3,4); to add(3,4,5); and hence method overloading is not polymorphism.
Java allows constructors of non-final classes to invoke any instance methods, even if those methods are abstract or non-final.
This is recognized as a bad practice (see., e.g., Effective Java 2nd Edition, Item 17), and isn't possible in C++ because of the defined constructor order.
My question is why this was allowed to begin with in the design of the Java language? It seemed like it could have been forbidden as a language restriction. Are there cases where doing this is necessary?
The Java language allows it because there is (was) no clear, uncontroversial reason to forbid it, specially if you consider that today's Java best practices were not necessarily known at the time the language was originally designed.
Note that a constructor calling an abstract or non-final method does work, because a subclass could override said method, and because the constructor may be executing on a newly-created instance of a subclass (due to constructor execution order from subclass to super class).
As far as I can tell, there is no case where doing it is necessary. But surely some third-party libraries out there do it, even if it is known to be a bad practice.
This question already has answers here:
What is the main difference between Inheritance and Polymorphism?
(18 answers)
Closed 5 years ago.
Do both inheritance and polymorphism constitute an IS-A relationship? And is it true that inheritance and "overriding" polymorphism happen in runtime while "overloading" polymorphism occurs in compile time? The reason I ask this is because a lot of forums seem to give conflicting and often confusing answers.
Thanks!
For your first part of the question I think Wikipedia provides a good definition:
In object-oriented programming, subtype polymorphism or inclusion
polymorphism is a concept in type theory wherein a name may denote
instances of many different classes as long as they are related by
some common super class. Inclusion polymorphism is generally
supported through subtyping, i.e., objects of different types are
entirely substitutable for objects of another type (their base
type(s)) and thus can be handled via a common interface.
Alternatively, inclusion polymorphism may be achieved through type
coercion, also known as type casting.
Another Wikipedia artile called Polymorphism in object-oriented programming seems to answer your questions very well. The second reference in this article called On Understanding Types, Data Abstraction, and Polymorphism also covers this matters in great detail.
This subtyping feature in Java is achieved, among other means, through inheritance of classes and interfaces. Although the subtyping features of Java may not be evident in terms of inheritance all the time. Take for example the cases of covariance and contravariance with generics. Also, arrays are Serializable and Cloneable although this is not evident anywhere in the type hierarchy. It can also be said that through primitive widening conversion, also numeric types in Java are polymorphic. And operator behave polimorphically depending on their operands.
At any rate, inheritance plays an important role in the implementation of some of this polymorphism.
Overloading vs Overriding
Your second part of the question seems to be about choosing the implementation of a given method. Evidently, if a class overrides a method and you create an instance of that class you want the overriden version of method to be invoked, even if you are accessing the object through a reference of the parent class.
The selection of the right implementation of method is done at runtime as you well pointed out, now the signature of the method to be invoked is decided at compile time. Since overloading is about different methods with the same name and different signature, that is why it is said that overriding method selection happens at compile time.
Overriding Method Selection at Compile Time
The Java Language Specification (JLS) in section 15.12 Method Invocation Expressions explains in detail the process that the compiler follows to choose the right method to invoke.
There, you will notice that this is a compile-time task. The JLS says in subsection 15.12.2:
This step uses the name of the method and the types of the argument expressions
to locate methods that are both accessible and applicable
There may be more than one such method, in which case the most specific one is chosen.
To verify the compile-time nature of this, you can do the following test.
Declare a class like this and compile it.
public class ChooseMethod {
public void doSomething(Number n){
System.out.println("Number");
}
}
Declare a second class that invokes a method of the first one and compile it.
public class MethodChooser {
public static void main(String[] args) {
ChooseMethod m = new ChooseMethod();
m.doSomething(10);
}
}
If you invoke the main, the output says Number.
Now, add a second more specific overloaded method to the ChooseMethod class, and recompile it (but do not recompile the other class).
public void doSomething(Integer i) {
System.out.println("Integer");
}
If you run the main again, the output is still Number.
Basically, because it was decided at compile time. If you recompile the MethodChooser class (the one with the main), and run the program again, the output will be Integer.
As such, if you want to force the selection of one of the overloaded methods, the type of the arguments must correspond with the type of the parameters at compile time, and not only at run time.
Overriding Method Selection at Run time
Again, the signature of the method is decided at compile time, but the actual implementation is decided at runtime.
Declare a class like this and compile it.
public class ChooseMethodA {
public void doSomething(Number n){
System.out.println("Number A");
}
}
Then declare a second extending class and compile:
public class ChooseMethodB extends ChooseMethodA { }
And in the MethodChooser class you do:
public class MethodChooser {
public static void main(String[] args) {
ChooseMethodA m = new ChooseMethodB();
m.doSomething(10);
}
}
And if you run it you get the output Number A, and this is Ok, because the method has not been overriden in ChooseMethodB and therefore the implementation being invoked is that of ChooseMethodA.
Now, add an overriden method in MethodChooserB:
public void doSomething(Number n){
System.out.println("Number B");
}
And recompile just this one, and run the main method again.
Now, you get the output Number B
As such, the implementation was chosen at runtime, and not recompilation of the MethodChooser class was required.
Polymorphism: Ability of different objects to receive same message and respond to differently.
Inheritance a way to achieve it, but not necessary. See Duck Typing
Overloading of a method is 'compile time syntax helper'- as every method gets a unique signature after compilation. Not really anything to do with polymorphism.
Polymorphism is an effect of inheritance. It can only happen in classes that extend one another.
Polymorphism does happen at runtime; I've never heard of "overloading polymorphism".
Inheritance happens at compile time, the moment you write:
class A extends B
{
}
I think you're right.
Polymorphism considers the runtime type of the object to decide wich method execute and the choice of which overloaded method to call is not dinamically decided at runtime, it depends on the types of the parameters at compilation time.
Only inheritance constitute an IS-A relationship. polymorphism has nothing to do with it.
"overloading" is example of polymorphism. You can learn more about run-time and compile-time polymorphism here
• Inheritance defines parent-child relationship between two classes, polymorphism takes advantage of that relationship to add dynamic behavior in your code.
• Inheritance encourages code reusability by allowing child class to inherit behavior from the parent class. On the other hand, Polymorphism allows the child to redefine already defined behavior inside the parent class. Without Polymorphism, it's not possible for a child to execute its own behavior while represented by a Parent reference variable, but with Polymorphism it can be done.
• Java doesn't allow multiple inheritance of classes but allows multiple inheritance of Interface, which is actually required to implement Polymorphism. For example, a class can be Runnable, Comparator and Serializable at the same time because all three are interfaces. This makes them pass around in code e.g. you can pass an instance of this class to a method which accepts Serializable, or to Collections.sort() which accepts a Comparator.
• Both Polymorphism and Inheritance allow Object-oriented programs to evolve. For example, by using Inheritance you can define new user types in an Authentication System and by using Polymorphism you can take advantage of the already written authentication code. Since, Inheritance guarantees minimum base class behavior, a method depending upon super class or super interface can still accept an object of the base class and can authenticate it.
Public class John {
public void setValue(){
this.value = 0;
}
public void setValue(int v){
this.value = v;
}
Now potentially how would i call these two methods??
John j = new John();
j.setValueO();
j.setValue(10);
Correct me if i am wrong.
Is function overloading a concept of polymorphism? If not, under which OOP branch does this come.
Encapsulation means Hiding the information and Abstraction means Hiding the implantation details. So when i do overload a method, do i carry anything on these two above... {Abstraction and Encpsulation}
Is Overloading compile time or runtime? Why do they call this for overloading and overriding?
Yes you are right, expect the typo which you have made?
Is function overloading a concept of polymorphism? If not, under
which OOP branch does this come.
Well speaking from historical point of view, it does come but still many argue that its not a form of polymorphism.
Overloading
The method functions differently based on the arguements.
Overriding
The method functions differently based on which class was used to instainate it.The method bark could sound differently for Class CAT and Class DOG.
Encapsulation means Hiding the information and Abstraction means
Hiding the implantation details. So when i do overload a method, do i
carry anything on these two above... {Abstraction and Encpsulation}
Nope. May be someone can answer on this much clearer.
Is Overloading compile time or runtime? Why do they call this for
overloading and overriding?
Compile time. In overriding the decision that method of which class is to be called is decided at runtime, hence it is runtime.
In overloading the method definition, availability based on the parameters passed in the method call is checked at compile time only.
Java does not identify methods by their names alone, but by their signatures. A signature is composed of the method name and the ordered list of parameter types. So, from a compiler and jvm point of view, those are two completely different methods. The fact that they share the name (and as a consequence a similar signature) has no meaning if not for humans.
Since signatures are used in .class files, the compiler is responsible for computing the signature of a method call, using method name and parameters, at compile time. The late binding that happens at runtime is related to polymorphism, beacuse the current instance on which a certain method is called could be an instance of a subclass that override a certain method, wether that method is also overloaded or not, in java, is not considered by the runtime at all.
You cannot have two method with the same signature in the same class. Notably, the return type of a method is not part of its signature, so you cannot have two method with the same and and same parameters but returning two different types.
In other languages, javascript for example, since parameters are always dynamic, the signature is only composed of the name of the method, which makes overloading impossible
As to the first part of your question, yes the code you showed is an example of overloading, well, assuming the first part is correct and the 0 in the second part is a typo.
I'm not familiar with how these topics are formally taught these days, but to my mind overloading isn't really related to polymorphism. It's just a convenient way for methods that more or less do the same thing (and often call each other) to share a name. I have no idea how to answer your second question. What is an "OOP branch"?
Again, I'm not quite sure how these tie in. Doesn't it depend on what the method actually does?
Well, think about it this way. In Java, when you call a method in general, leaving overloading aside, at what phase does the system figure out which method you're calling (as opposed to which class's implementation of that method)? As to the origin of those terms, honestly that should be pretty easy to look up.
Since function overloading can work very well without objects, I do not see any reason for it to be an OOP concept at all. For the question whether it's polymorphism, it does fulfill the general requirements and according to Wikipedia is a form of polymorphism.
In general, when you create a method you always do both (you abstract away some general functionality and you hide the information of the internal workings of the function). Overloading does not add to neither, IMO. (Even though through overloading and the gained polymorphism you could argue to gain in abstraction, since the function becomes more generic, it is IMO still on the same level of abstraction.)
Overload resolution is - which was suprising to me at first - compile time. This is in contrast to the mentioned overriding. (So its in that sense not the same kind of polymorphism, as one is runtime and the other one is compile time.)