What is overloading in Java? - java

I don't understand the overloading in Java. Is there a relation with polymorphism ? It seems very abstract for me.
I come more from Javascript language ? Would this apply so in Javascript ?

Overloading means that the same method name can be defined with more than one signature — the list of formal parameters (and their types).
Overloading means different things in different languages. Java is strongly typed (some might say "fiercely typed" in fact). It just means that there can be different versions of a function and the compiler can tell which one is intended by looking at the types of parameters in a call to the function (method).
JavaScript is not like that; the formal parameters to a function are just references by name in the function body, but otherwise there's nothing special about them and any function can be called with any arguments and any number of them.
Some languages use "overloading" as a runtime concept. In Erlang, it's not the types of arguments that matter when picking from several alternative versions of a function; it's the values.
edit — #MarkoTopolnik points out that the issue isn't so much about the "strength" (or "ferocity" :-) of the type system, but about how static it is. Java insists on types being explicitly declared pretty much everywhere, while JavaScript (excepting some of the new typed array constructs) doesn't.

Overloading is feature that allows having 2 methods with the same name and different signature in one class, e.g.
public void foo();
public void foo(int i);
Now you can call method foo() without arguments or with one int argument and different methods will be executed.
You are probably confused with overloading and overriding. Overriding indeed relate to polimorphysm. This is ability to overrride (change) functionality of base class into subclass. For example if Child extends Base and both have method foo() the foo() of child overrides implementation of Base. Similar feature indeed exists in JavaScript.

if you have following method in your class
public void calculate() {}
Following are some overloaded versions of it.(Note same name)
public void calculate(int i) {}
public void calculate(int i, int j) {}
But following is not an overloaded one of above method. This method differs from the original method only just because the return type. Methods with same signature but with different return types are not allowed in java.
public int calculate(int i) {}

The method which have same name with multiple definition is known as overloading
may be its differ from argument type and number of arguments.
Example
import java.io.*;
class demoOverloading
{
int add(int x,int y) //method definition
{
return (x+y);
}
double add(double x,double y) //method definition
{
return (x+y);
}
}
public class JavaApplication4
{
public static void main(String[] args)
{
demoOverloading demo=new demoOverloading(); //creating object for above class
System.out.println("Sum of Integer "+demo.add(10,20)); //calling integer add method
System.out.println("Sum of double "+demo.add(33.44,67.5)); //calling double add method
}
}
The above example having two methods having same name add but one contains int and another contains double arguments, like this we can made with different argument,,
Also possible made difference in number of arguments..
Thank you

Related

must two overloading methods have same return value, to be called "overloading"?

Oracle people said, they must do so, but I just feel weird...
package com.xenoamess;
public class Main {
public int add(int a, int b) {
return a + b;
}
public long add(long a, long b) {
return a + b;
}
}
For example, CAN'T we call the two functions above "overloading"? and if can't, why?
CAN'T we call the two functions above "overloading"?
We can call it overloading, because the methods have different parameter types.
In the JLS, overloading is defined as:
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded.
"Override-equivalent signatures" basically means "same signatures when type erasure is taken into account" (Learn more here).
The signature of a method doesn't include the return type:
Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.
I think what the question in the screenshot was getting at, is that you can't overload methods by only changing the return type. I would say the options are worded rather badly.
same functions headers with different parameters is called overloading , so I think your example is overloading .
and i think it's about the headers only not the return type .

Is all dynamic binding a kind of polymorphism?

Is all dynamic binding considered to be polymorphism? Specifically, I'm talking about Java. If not, please explain both terms.
What I know: not all inheritance is polymorphism but inheritance is used in all polymorphism.
First of all dynamic binding (or late binding) is an improper term. You are talking about dynamic dispatch which is a different thing.
Dynamic binding is choosing which implementation of a method will be called at runtime, but this doesn't happen in Java. But you have dynamic dispatch which is the ability to choose the correct polymorphic implementation of a method at compile time (which usually translates to choosing the most specialized version of the method/function).
But I wouldn't say that dynamic dispatch is polymorphism, I'd say that to support polymorphism you need a mechanism to choose the correct implementation of a method and this is dynamic dispatch.
Inheritance is a kind of polymorphism called subtyping (or subtype polymorphism) so, contrary to what you say, inheritance is always a form of polymorphism, but other kinds of polymorphism exist, think about:
ad hoc polymorphism (implemented through overloading) where the same function has different meanings when applied to different arguments
parametric polymorphism (implemented with Generics in Java) where you have types with type variables so that a single type can express infinite number of types by binding the variable to a specific type (or a class of types), think about List<Integer>
If the method call is decided at runtime- it is dynamic polymorphism. If the method call is decided by compiler during compile time it is called static polymorphism.
Example:
public static void eat (Veg vegetable) {
System.out.println("I am vegetarian");
}
public static void eat(Meat meat) {
System.out.println("I am non-vegetarian");
}
//if your main is this way
public static void main(String args[])
{
Veg v = new Meat();
callEat(v);
}
It prints "I am vegetarian" . This is decided by compiler on runtime. Its also called as method overriding.
int add (int a , int b){
return a+b;
}
int add(int a, int b, int c){
return a+b+c;
}
void main (){
add(1,2);
add(1,2,3);
}
Here the function is choosen depending on the parameter passed even when the name and return type of the method is the same. This is done at compile time. This is static polymorphism. It is also called as method overriding.

Name Hiding in C++ vs Java [duplicate]

This question already has answers here:
Function with same name but different signature in derived class not found
(2 answers)
overloaded functions are hidden in derived class
(2 answers)
Closed 8 years ago.
I learned something new about C++ the other day; the following does not work:
class ParentClass {
public:
void someFunction() { printf("ParentClass::someFunction()"); }
};
class ChildClass : public ParentClass {
public:
void someFunction(int a) { printf("ChildClass::someFunction(int)"); }
};
int main() {
ChildClass childClass;
// This call is a compiler error.
// I would expect it to call ParentClass::someFunction()
childClass.someFunction();
}
However, doing exactly the same thing in Java (among other languages) works just as I would expect:
public class ParentClass {
public void someFunction() { System.out.println("ParentClass"); }
}
public class ChildClass extends ParentClass {
public void someFunction(int a) { System.out.println("ChildClass"); }
}
public class Main {
public static void main(String[] args) {
ChildClass childClass = new ChildClass();
// The following prints "ParentClass"
childClass.someFunction();
}
}
So what gives in C++? Why does this hide the name instead of overloading it?
If you're asking what the rules are, then name lookup stops as soon as it finds one or more overloads within one scope, and doesn't look at any wider scopes. So, in your case, the search for someFunction starts in the scope of ChildClass, finds a match, and stops.
Only the name is considered, not its usage (e.g. number of arguments in a function call), accessibility, or anything else. If none of the overloads are usable, the search still doesn't continue to other scopes, and the program is ill-formed.
If you're asking why the rules are like that, consider the case where, initially, there's just one function:
struct Base {};
struct Derived : Base {void f(int);}
and someone calls it with a type that doesn't quite match
Derived d;
d.f(42.0); // OK: double converts to int
Now suppose someone, who knows nothing about Derived, decides that Base could do with another function:
struct Base {
void f(double); // Completely unrelated to D::f
};
Under the C++ rules, that function will be ignored by the code using D::f, which will continue to work as before. If the new function were considered as an overload, it would be a better match, and the code using D::f would suddenly change behaviour, potentially leading to much head-scratching and lengthy debugging sessions.
If you want to include all the base-class functions in the scope of the derived class to be considered as overloads, then a using-declaration will do that. In your case:
using ParentClass::someFunction;
Alternatively, to avoid the situation described above at the cost of some tedious verbiage, you could write forwarding function(s) for the specific overload(s) you want:
void someFunction() {ParentClass::someFunction();}
In C++, name hiding can take place when one function in base class has the same name as one function in derived class. The reason is phases of the function call process.
In C++, phases of the function call process are as following
Name lookup
Overload resolution
Access control
Name lookup stops looking for other names as soon as it finds a name in derived class ChildClass. Therefore, ChildClass::someFunction() hides any function with name someFunction in ParentClass.
After the name lookup process, overload resolution fails since there is no someFunction() in ChildClass.
The core difference is that in C++ the method signature is essentially just the method name whereas in Java it is the method name and its parameters.
In your case, by using the same method name you are overriding the parent method so the parent method taking no parameters is not available any more. In Java you must override with a method that both has the same name and has the same parameters to override a method so in your case they are both still available.
There is a completely different debate about whether the return type should also be included - let's not go there.

Java - Interface Methods

Just playing around with interfaces and I have a question about something which I can't really understand.
The following code doesn't run, which is the behaviour I expect as the interface method requires the method to work for any object and the implemented method has the signature changed to only allow string objects.
interface I {
public void doSomething(Object x);
}
class MyType implements I {
public void doSomething(String x) {
System.out.println(x);
}
}
However, using the following block of code, I was shocked to see that it did work. I thought it would not work as we are expecting to return an object and the implemented method will only return a string object. Why does this work and what is the difference between the two principles here of passed parameters and return types?
interface I {
public Object doSomething(String x);
}
class MyType implements I {
public String doSomething(String x) {
System.out.println(x);
return(x);
}
}
public Object doSomething(String x);
has to return something. Anything, in fact, so long as it is some type of object. So if you implement
public String doSomething(String x) {stuff}
that's fine, because it does in fact return an Object. The fact that the object it will return will always be a String is no big deal.
The reason the first example doesn't work, is because accepting only strings is more limiting than accepting any object. But returning only strings is fine.
For an analogy, let's say you got a contract to paint a building, and you're gonna hire some employees to help you out. The contract requires that you hire any painter that applies, regardless of how tall they are, but doesn't specify what color paint to use. If you only hired painters over 6 ft tall (that's the input, accepting only String instead of all Object), you'd be violating the contract. But choosing to paint with only blue paint (returning only strings) is just fine, because the contract didn't specify color, only that you must paint the building.
It works because a String is an Object.
This has to do with covariant return types, introduced in Java SE 5.0.
You can see more details in http://docs.oracle.com/javase/tutorial/java/javaOO/returnvalue.html
From the java language specification:
Return types may vary among methods that override each other if the return types are reference types. The notion of return-type-substitutability supports covariant returns, that is, the specialization of the return type to a subtype.
So in other words, it works as you did it, but it would not work if the return type in the interface is String, and in the implementing class is Object.
The principle behind this behaviour is called covariant return type. In this particular case, the overrriding type may "narrow" the originally declared parameter type.
This means that as String is subclassing Object, Object may be substituted by String.
The reason why the first example doesn't work and the second example does, is because function prototypes are defined by the name and all parameters only, but not the return type. In the first example, there is a difference, so the compiler thinks they are two different functions.
In the second example, the implemented function does not broaden the type, but instead specializes the type (String is a specialization of Object), so it works.
Likewise you can limit the visibility of the implemented method, but not broaden it.
Furthermore, Java has generics, which are useful in this context.
Example:
interface I<T>
{
public void doSomething(T x);
}
class MyType implements I<String>
{
public void doSomething(String x)
{
System.out.println(x);
}
}
method signature does not take into account the return type. (Though is is an error to declare two methods with the same signature but different return type). So:
void doSomething(Object)
void doSomething(String)
Are simply two methods and none overrides or implements the other
string class is inherited from object class, so only this code works.

Overloading of Math.sqrt : overloading method seems to hide the original one

trying to overload the java.lang.Math.sqrt static method for int type :
import static java.lang.Math.sqrt;
class Test
{
private static double sqrt(int n)
{
return sqrt(1.0 * n);
}
public static void main(String[] args)
{
System.out.println(sqrt(1));
}
}
an odd error arises :
Test.java:7: sqrt(int) in Test cannot be applied to (double)
return sqrt(1.0 * n);
^
1 error
But when explicitly referencing the java.lang.Math.sqrt method all is going fine :
class Test
{
private static double sqrt(int n)
{
return Math.sqrt(1.0 * n);
}
public static void main(String[] args)
{
System.out.println(sqrt(1));
}
}
The compiler used is the standard javac, version 1.6.0_16.
So the questions are :
Why is the compiler not able to resolve the overloading in the first case ?
Where does this behavior is specified in the java language specifications ?
Thanks in advance.
You can only overload methods in the same class. I.e. if you import a static method of another class and then define your own method with the same name, there will be no overload resolution. The imported version of the method will simply be ignored.
Regarding where this behavior is specified: The language specification defines overloading like this:
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded.
Note that it says "two methods of a class". So methods imported from another class are simply not considered.
So since your definition is not an overload of Math.sqrt, it shadows it as per section 6.3.1 of the definition:
A declaration d of a method named n shadows the declarations of any other methods named n that are in an enclosing scope at the point where d occurs throughout the scope of d.
That's quite normal.
By writing this code, you didn't overload the Math.sqrt method in any way, you simply defined a Test.sqrt(int) as an argument.
Then there is the question of your error message.
When defining the Test.sqrt method, you overload (in this class) the static import you made.
So, when calling sqrt(1.0 * n), the compiler consider you try to call Test.sqrt(int) with a double, swhich is obviously not possible.
You're not actually overloading. Things are being hung up over an ambiguity; the compiler sees return sqrt(1.0 * n);, it assumes you're talking about the sqrt(int) function in class Test, not the one in lang.Math. This is preferable behavior; after all, you probably don't want to have to specify class.method every time you're trying to call a member function. And the compiler doesn't resolve it is because in your particular situation, it assumes you've made a mistake and doesn't realize you intended to call the sqrt in lang.Math.
Yes, sqrt(int) in Test cannot be applied to (double)
Rename your function with different name, if you wish to call Math.sqrt:
private static double mysqrt(int n)
{
return sqrt(1.0 * n);
}
In the first call the method referred is the one which you have return which expect int to be its parameter but you are sending double to it. so it gives a compiler error.
But with the second call you are referring to Math.sqrt() which works fine.

Categories

Resources