I am asking this question because in Collection I see that Arrays.sort() is overloaded, so I am wondering how someone can say that a static method is overloaded, when static methods are loaded at class loading time, and overloading is performed after class loading time.
My main question is: overloading and overriding are performed after class loading time; that's why they are visible to objects and invisible to static parts. So can static methods be overloaded?
Compile time and class load time are not the same thing. And run time (in the sense that I use the term in the following ...) is something different again.
Overload analysis is performed at compile time, for both static and instance method calls. The same is true for cases where one static method shadows another static method - it is resolved at compile time.
Override dispatching (for instance methods) occurs at run time; i.e. when the method call actually occurs, depending on the actual object that is the "target" object.
why Arrays.sort() is overloaded , when it is static
Why shouldn't it be?
As I said, both static and instance methods can be overloaded. (Overriding is restricted to instance methods, and instance methods only ... but overloading can be used with all kinds of methods, and to constructors too.)
Also "loading" and "overloading" are totally unrelated concepts. "Loading" is about getting classes (in this case) into memory, but "overloading" is about different methods with different signatures that have the same name.
Both static and dynamic polymorphism are part of polymorphism.
In static polymorphism, the overloading is resolved at compile time, in dynamic, it's resolved at runtime. In spite of that both are valid cases of overloading.
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
I'm writing an explanation for some code for a course, and have been accidentally using the words method and function interchangeably. I decided to go back over and fix the wording, but ran into a hole in my understanding.
From what I understand, a subroutine is a function if it doesn't act on an instance of a class (its effect is restricted to its explicit input/output), and is a method if it operates on an instance of a class (it may carry out side effects on the instance that make it impure).
There's a good discussion here on the topic. Note that by the accepted answer's definitions, a static method should actually be a function because an instance is never implicitly passed, and it doesn't have access to any instance's members.
With this is mind though, shouldn't static methods actually be functions?
By their definition they don't act on particular instances of a class; they're only "tied" to the class because of relation. I've seen a few good looking sites that refer to static subroutines as "methods" though (Oracle, Fredosaurus, ProgrammingSimplified), so either they're all overlooking the terminology, or I'm missing something (my guess is the latter).
I'd like to make sure I am using the correct wording.
Can anybody clear this up?
This quote from 8.4.3.2 may help:
A method that is declared static is called a class method.
A method that is not declared static is called an instance method [...].
Class methods: associated with a class.
Instance methods: associated with an instance.
Java just wants you to "think object-oriented". Also, static methods have access to a surrounding scope which may include state. In a way, the class is like an object itself.
The simple answer is that when Java decided to call everything a "method", they didn't care about the distinction between a function and a method in theoretical computer science.
Static methods are not exactly functions, the difference is subtle, but important.
A static method using only given input parameters is essentially a function.
But static methods may access static variables and other static functions (also using static variables) so static methods may have a state which is fundamentally different to a function which are by definition stateless.
(ADDENDUM: While programmers are often not so strict with using "function" as definition, a strict function in computer science can access only input parameters). So defining this case of accessing static fields it is not valid to say that static methods are always functions.
Another difference which justifies the usage of "static method" is that you can define in C derivates global functions and global variables which can be accessed everywhere. If you cannot access the class which contain static methods, the methods are inaccessible, too. So "static methods" are limited in their scope by design in contrast to global functions.
In Java, a user-defined class is actually an instance of a subclass of java.lang.Class.
In this sense, static methods are attached to an instance of a conceptual class: they are attached to an instance of a subclass of java.lang.Class.
With this in mind, the term "class method" (an alternate name for Java's static methods) begins to make sense. And the term "class method" can be found in many places: Objective C, Smalltalk, and the JLS -- to name just a few.
In computer science function clearly maps to a static method. But "method" of a class is a bit generic, like "member" (field member, method member). There are wordings like
Data members and method members have two separate name spaces: .x and .x() can coexist.
So the reason is, that as the philosoph Ludwig Wittgenstein said, Language is a tool with different contexts. "Method" is a nice moniker in the citation above to categorize a "member".
Your thinking is right and it makes sense. It's just not established terminology in the Java community. Let me explain some internals that can help understand why the terminology subsists.
Java is a class based object oriented language. A method is always member of a class or instance (This is a general statement valid for other programming languages too). We think of class and instance being both objects.
Instance method (dynamic)
You cannot invoke this method from a class directly, you have to create an instance. Each instance references that method. You can overwrite a method definition with the exact same method signature (when subclassing), i.e. the reference points to a different method (which has the same signature, but can have a different method body). The method is dynamic.
Class method (static)
You only can invoke this method from the class directly, i.e. you don't need to create an instance of that class. There is only one global definition of that method in the whole program. You cannot overwrite the exact same method signature when the method is declared static, because there is only one definition valid for the whole program. Note that the method is member of the class object itself, the instances have all the same unique (and fix) reference to that method.
Here is another take on the terminology, using Scala as a mnemonic:
In Scala you have objects, which are singleton instances of an implicitly defined class 1.
Per your definition, we can call these subroutines belonging to the object methods, as they operate on a single instance of the class.
Additionally the object will also define class A, and create all of the methods in object A as static methods on class A (for interfacing with Java) [2].
Therefore we can say that the static methods of Java class A access the same members as the Scala singleton instance, which per your definition then deserve to be called (static) methods of class A.
Of course, the main difference is - method can use static fields, not only method parameters.
But there is additional one - polymorphism!
Results of evaluation Class A.doTheSameStaticMethod() and ClassB.doTheSameStaticMehod() will be depends of class. In this case function is impotent.
Each class has an object to represent it that is an instance of a subclass of the Class class. Static methods are really instance methods on these objects that are instances of a subclass of Class. They have access to state in the form of static fields, so they are not restricted to being just (stateless) functions. They are methods.
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.)
I have a Junit4 test case which statically imports the org.junit.Assert.assertEquals method(s).
import static org.junit.Assert.assertEquals;
In this class I have created a utility method for asserting some complex internal classes which do not implement equals (and also have a hard time implementing it).
private void assertEquals(MyObj o1, MyObj o2)
{
assertEquals(o1.getSomething(), o2.getSomething());
assertEquals(o1.getSomethingElse(), o2.getSomethingElse());
...
}
I expected the code to behave as if I am "overloading" the assertEquals method(s) that I'm importing, but it looks like my private non-static method is hiding the statically imported methods. I also tried turning my method to be public and static (all permutations) but with no success - I had to rename it.
Any reason why it behaves this way? I couldn't find any reference to this behavior in the documentation.
What you observed is calling Shadowing. When two types in java have the same simple name, one of them will shadow the other. the shadowed type then can't be used by it's simple name.
The most common type of shadowing is a parameter to hide a field. usually result in setter code to look like setMyInt(int myInt) {this.myInt = myInt; }
Now let's read the relevant documentation:
A static-import-on-demand declaration never causes any other declaration to be shadowed.
This indicate a static import on demand always comes last, so any type with the same simple name as a import on demand declaration will always shadow (hide) the static import.
Overloading and overwriteing works in an inheritance tree. But a static import doesn't build a inheritance.
If you want to use the assertEquals of junit in your own assertEquals method you must qualify it with the className e.g. Assert.assertEquals.
Use a nonstatic import of org.junit.Assert.
You have stumbled onto method hiding, where the presence of a local method "hides" one from another class (often a super class).
I have always felt that statically importing methods is, while syntactically possible, somehow "wrong".
As a style, I prefer to import the class and use TheirClass.method() in my code. Doing so makes it clear that the method is not a local method, and one of the hallmarks of good code is clarity.
I recommend you import org.junit.Assert and use Assert.assertEquals(...).
This makes sense. Suppose javac does what you want, it picks your assertEquals(MyObj, MyObj) method today. What if tomorrow org.junit.Assert adds its own assertEquals(MyObj, MyObj) method? The meaning of invocation assertEquals(mo1,mo2) changed dramatically without you knowing it.
At question is the meaning of the name assertEquals. Javac needs to decide that this is a name of method(s) in org.junit.Assert. Only after that, it can do method overloading resolution: examine all methods in org.junit.Assert with the name assertEquals, pick the most appropriate one.
It's conceivable that java could handle method overloading from multiple classes, however as the first paragraph shows, it causes great uncertainty to developer of which class the method he is calling. Because these classes are unrelated, method semantics can differ greatly.
If at compile time, it's without any doubt to developr which class the method belongs to, it is still possible that the class will overload the method tomorrow therefore changing the target method invoked.
However, because that is done by the same class, we can hold it responsible. For example, if org.junit.Assert decides to add a new assertEquals(MyObj, MyObj) method, it must be aware that some previous invocations of assertEquals(Object,Object) are now rerouted to the new method, and it must make sure that there's no semantics change that will break the call sites.