How is this called overloading - Java [duplicate] - java

This question already has answers here:
Java overloading and overriding
(9 answers)
Closed 5 years ago.
I have this class BindingSample with a method that takes no parameter
public class BindingSample {
public void printMsg(){
System.out.println("Binding Sample no parameter");
}
}
And another class that extends the BindingSample and uses the same method signature but adds a parameter to it
public class application extends BindingSample {
public void printMsg(int i){
System.out.println("Changed my value " + i);
}
public static void main(String[] args) {
application app = new application();
app.printMsg(5);
}
}
The output is Changed my value 5
Why did it work even if the parameters are different? And why is it called overloading? I don't think it's overriding because to override a method, the method signature and its parameter should be the same.

Why did it work even if the parameters are different?
You application class has a printMsg method that takes a single int argument. Therefore app.printMsg(5) works.
Note that making the following change will cause your code not to pass compilation:
BindingSample app = new application();
app.printMsg(5);
since now the compiler can't find a printMsg method in the BindingSample class that takes an int argument.
And why is it called overloading? I don't think it's overriding because to override a method, the method signature and its parameter should be the same
Overriding and overloading are two different concepts.
Method overloading occurs when multiple methods share the same name but have different number of arguments or different types of arguments.
Your application class has two printMsg methods (one inherited from its super class) with a different number of arguments. Hence this is method overloading.

Overloading means just the names of the methods should be same. Everything else can be different (e.g. arguments, return types, throwable exceptions etc). As both the methods in the example have same name, it's called Overloading.
The reason why it works is, Overloading is compile time phenomena, compiler just checks for accessibility of the method to the object that's calling it. As you are instantiating application class and calling printMsg method with int argument. It works fine because of the method being present in the class (or being accessible to that object).

Related

Base method hiding in C# and Java

I am coming from Java background and currently learning C#. I just had a big surprise regarding (what I perceive as ) a difference in a way that an object accesses methods from base/derived class. Here is what I mean:
In Java if I do something like this
class InheritanceTesting
{
public void InheritanceOne()
{
System.out.println("InheritanceOne");
}
}
class NewInherit extends InheritanceTesting
{
public void InheritanceOne()
{
System.out.println("InheritanceTwo");
}
}
then run the following:
public static void main(String[] args) {
InheritanceTesting inh = new NewInherit();
inh.InheritanceOne();
}
I get the result:
InheritanceTwo
If I do exactly the same in C#:
class InheritanceTesting
{
public void InheritanceOne()
{
Console.WriteLine("InheritanceOne");
}
}
class NewInherit : InheritanceTesting
{
public new void InheritanceOne()
{
Console.WriteLine("InheritanceTwo");
}
}
Then:
InheritanceTesting inh = new NewInherit();
inh.InheritanceOne();
result is
InheritanceOne
I remember being taught in Java that "object knows what type it is instantiated to", therefore, no surprises when I call the overridden method. Does this mean that the situation is the opposite in C#? Object only "knows" its declared type? If so, what is the logic/advantage in that? It seems to me that Java treats base classes like interfaces - here is your type and here is your actual implementation. I am new to C# and maybe I am missing something obvious here?
A slightly more interesting case is the following
class InheritanceTesting
{
public void InheritanceOne()
// Java equivalent would be
// public final void InheritanceA()
{
Console.WriteLine("InheritanceA - One");
}
public virtual void InheritanceB()
// Java equivalent would be
// public void InheritanceB() // note the removing of final
{
Console.WriteLine("InheritanceB - One");
}
}
class NewInherit : InheritanceTesting
{
public new void InheritanceOne()
// There is no Java equivalent to this statement
{
Console.WriteLine("InheritanceA - Two");
}
public override void InheritanceB()
// Java equivalent would be
// public void InheritanceB()
{
Console.WriteLine("InheritanceB - Two");
}
}
What you are seeing are some of the difference between C# and Java, you can get C# to behave like Java as the method InheritanceB will show.
C# methods are final by default, so you need to take a positive action to make it possible to override a method by marking it as virtual. So the virtual method InheratanceB will behave like you expect methods to behave, with method dispatch based on the object type, not the reference type. e.g.
NewInherit example = new NewInherit();
InheritanceTesting secondReference = example;
example.InheritanceB();
secondreference.InheritanceB();
Will both produce InheritanceB - Two as the method InheritanceB was virtual (able to be overriden) and overridden (with the override method).
What you where seeing is called method hiding, where the method can not be overriden (non-virtual) but can be hidden, hidden methods are only hidden when the reference (not the object) is of the derived type so
NewInherit example = new NewInherit();
InheritanceTesting secondReference = example;
example.InheritanceA();
secondreference.InheritanceA();
Will produce InheritanceB - Two first and InheritanceB - One second. this is because (at least in the simple cases) invocation of final methods is bound at compile time based on the reference type. This has a performance benifit. Binding of virtual methods needs to be differed to runtime as the compiler may not be aware of the instances class.
In practice method hiding is not widely used, and some organisation have coding standards forbidding it. the normal practice is to mark the methods you expect a sub-class to be able to override as virtual and in the sub-class use the keyword override.
More directly answering your questions
Does this mean that the situation is the opposite in C#? Object only
"knows" its declared type?
No, c# knows both the constructed type (instance) and the declared type (reference). It uses the instance type for overridden methods and the declared type for final methods even if the instance has hidden the method.
If so, what is the logic/advantage in that?
No the case, I believe there are performance benefits in binding at compile time where possible, e.g. allow in-lining of methods. Also as explained there is not a loss of flexibility as you can have the same behaviour as Java by using the virtual and override keywords.
Java treats methods as virtual by default, C# methods are non-virtual by default. If you want the same behavior in C# use the virtual keyword. In Java you can use final to ensure an inherited class doesn't override a method.
The reason C# methods are not virtual by default is most likely to prevent people from being able to change every inherited functions behavior on the fly in ways the base class designer didn't intend. This gives more control to the base class designer and ensures that inheritance is carefully and willfully planned for rather than just done on the fly.
Java makes methods virtual by default, while in C# you have to explicitly enable virtual inheritance.
That's why you added the new modifier right? Because you got a warning about it? That's because without a method being virtual, you replace it statically if in a derived class you redefine it. If instead of calling InheritanceOne() through a base pointer you call it through a derived pointer you'll get the result you expect -- the compiler chooses non-virtual methods at compile time, based on compile time only information.
TL;DR: Anytime you want to use inheritance for a method, make it virtual in C#. new is one of the worst things in the language for methods, it has no real use and only adds gotchas to your code.
You might think that you have written the same thing (same words), though you did not (you used new keyword in c# version) but C# equivalent of what you wrote in Java is this.
class InheritanceTesting
{
public virtual void InheritanceOne()
{
Console.WriteLine("InheritanceOne");
}
}
class NewInherit : InheritanceTesting
{
public override void InheritanceOne()
{
Console.WriteLine("InheritanceTwo");
}
}
In Java, by default all methods, except privates and statics of course, are virtual and any method has same signature with a super class method is an override.
By default, every method in Java can be overridable by its sub classes(unless private/static etc).
In C#, you have to make a method virtual if it has to be overriden by sub classes.
In your C# example, its not a overriden method so the behaviour is expected.

null behavior in function overloading with polymorphism [duplicate]

This question already has answers here:
Strange Java null behavior in Method Overloading [duplicate]
(4 answers)
Behavior of method overloading in java [duplicate]
(1 answer)
Closed 9 years ago.
I have the following code
public class HelloWorld {
public void printData (Test t) {
System.out.println("Reached 1");
}
public void printData(NewTest t) {
System.out.println("Reached 2");
}
public static void main(String args[]) {
HelloWorld h = new HelloWorld();
h.printData(null);
}
}
and I have two simple classes
class Test {
}
class NewTest extends Test {
}
and the output I got is Reached 2
Why the second function was selected for executing and not the 1st one? Also when I tried the same code by making another class NewTest2 extending Test and analogous printData() function it gave me compile time error. Is there any rule to select which function must be executed and when?
Why the second function was selected for executing and not the 1st one?
Because the method taking NewTest is more specific than the method taking Test, and both are accessible and applicable.
However, when you've got two subclasses of Test, neither conversion is more specific than the other, hence the call is ambiguous.
See JLS section 15.12.2.5 for the exact rules involved:
If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.
The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error.
What IDE do you use ?
In Eclipse "h.printData(null)" is marked red with this error:
The method printData(Test) is ambiguous for the type HelloWorld.
In this case you need to cast null like that:
"h.printData((Test)null)"

Overloading method calls with parameter null [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Method Overloading for NULL parameter
In the code below the output is
String
and if I remove the method with the parameter of type String then the output is
Object
I know how overloading of methods acts when the parameter types don't match exactly but I can not understand how null can be treated as an Object and/or a String parameter.
What is the explanation for this?
class C {
static void m1(Object x) {
System.out.print("Object");
}
static void m1(String x) {
System.out.print("String");
}
public static void main(String[] args) {
m1(null);
}
}
It always uses the most specific method according to the Java specs, section 15.12.2.5.
The intro is reasonably specific about it:
If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.
The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error.
Generally speaking, and at least for code readability, it's always best to try to be as explicit as possible. You could cast your null into the type that matches the signature you want to call. But that's definitely a questionable practice. It assumes everyone knows this rule and makes the code more difficult to read.
But it's a good academic question, so I +1 your question.
When multiple overloads match a signature, Java picks the most specific method from among them.
The value of null matches both Object and String, but String is a subclass of Object, so String is picked. If you add another overload with a sibling of String in the class hierarchy, you'd get a compile error.\
// DOES NOT COMPILE
class C {
static void m1(Object x) {
System.out.print("Object");
}
static void m1(String x) {
System.out.print("String");
}
static void m1(Integer x) {
System.out.print("Integer");
}
public static void main(String[] args) {
m1(null);
}
}
Here is a link to a post that discusses your code example at some length.
If you need to force the call of a aprticular overloaded method when passing null as parameter, you have to cast it, like this:
m1((String)null);
By doing this, you make sure you're calling the correct overloaded version of the method.
You have to set the type of null to tell Java what function you want to call.
So you do: m1((Object) null); to call the implementation with the Object parameter and you do m1((String) null); to call the other one.
1. As String is also an object the JVM got confused to call which method at runtime.
2. If you want to specify which method to call at runtime, you can do this by explicit casting
eg:
m1((String)null);

Are Interfaces "Object"? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Do interfaces inherit from Object class in java
package inheritance;
class A{
public String display(){
return "This is A!";
}
}
interface Workable{
public String work();
}
class B extends A implements Workable{
public String work(){
return "B is working!";
}
}
public class TestInterfaceObject{
public static void main(String... args){
B obj=new B();
Workable w=obj;
//System.out.println(w.work());
//invoking work method on Workable type reference
System.out.println(w.display());
//invoking display method on Workable type reference
//System.out.println(w.hashCode());
// invoking Object's hashCode method on Workable type reference
}
}
As we know that methods which can be invoked depend upon the type of the reference variable on which we are going to invoke. Here, in the code, work() method was invoked on "w" reference (which is Workable type) so method invoking will compile successfully. Then, display() method is invoked on "w" which yields a compilation error which says display method was not found, quite obvious as Workable doesn't know about it. Then we try to invoke the Object class's method i.e. hashCode() which yields a successful compilation and execution. How is it possible? Any logical explanation?
The intuitive answer is that regardless of what interface you refer to, the object implementing the interface must be a subclass of Object.
Section 9.2 of the JLS specifically defines this behaviour: http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.2
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
i.e. all interfaces are assumed to contain method signatures corresponding to methods in the Object class.
I think what's happening here is that even though w is known only to be Workable, all objects must derive from Object, so no matter what class w eventually is, it must have the Object methods.
The reason w.display() doesnt work is as you have save the reference as your interface type. The compiler only sees the methods exposed by the interface. If you were to call ((B)w).display() this would work. You are able to call hashCode() as the compiler is smart enough to know that interfaces are inherited by Objects and all object's superclass is Object

Java overloading and overriding

Suppose i have two methods in a class say
public void eat(int i,String s) and
public void eat(String s, int i)
then what is it like. Overloading or overriding?
Overloading means two methods or more with the same name but with different parameters just like your example.While Overriding you implement a method from an interface or abstract class so the method in the super class has an implementation and in the subclass has a different one, Still they have the same method name and parameters.
That would be method overloading, as it meets the conditions for method overloading:
Must have different argument lists
May have different return types, if
argument lists are also different
May have different access modifiers
May throw different exceptions
Also overriding can happen only when inheritance is involved. Since both of your methods are in the same class it cannot be overriding.
This is overloading. Overriding is used in inheritance when you give different implementation to the same method signature.
That's overloading. In brief:
Overriding = replacing
Overloading = give more options
Method Overloading simply means providing two separate methods in a class with the same name but different arguments while method return type may or may not be different which allows us to reuse the same method name.
Method Overriding means defining a method in the child class which is already defined in the parent class with same method signature i.e same name, arguments and return type.
Difference Between Method Overloading and Method Overriding
For more details, you can read Everything About Method Overloading Vs Method Overriding.
Kind of rules about overloading and overriding:
Constructors can be overloaded but not overridden.
Abstract methods must be overridden by the first concrete sub-class.
The overriding method:
must have same argument list,
must have same return type (it can also be a subclass of parent's class' return type,
must not have a more restrictive access modifier,
may have a less restrictive access modifier,
must not throw new or broader checked exceptions,
may throw fewer or narrower checked exceptions, or any unchecked exception.
final methods cannot be overridden.
Only inherited methods may be overridden, and remember that private methods are not inherited.
In a subclass use: super.overriddenMethodName() to call superclass' overridden method.
Overloaded methods:
must have different argument lists,
may have different return types, if argument lists are also different,
may have different access modifiers,
may throw different exceptions.
Methods from a superclass can be overloaded in a subclass.
Polymorphism applies to overriding but not to overloading.
Object type (not the reference variable's type) determines which overridden method is used at runtime.
Reference type determines which overloaded method will be used at compile time.
*Taken from Sun Certified Programmer for Java 6 Study Guide by Kathy Seirra, Bert Bates.
Overloading : In Java Overloading is a Process where a class Contains multiple implementation of methods or constructor by differentiating there no of arguments or types of arguments.
public class TestDemo
{
public void disp(String c)
{
System.out.println(c);
}
public void disp(String c, int n)
{
System.out.println(c+" "+n);
} }
class Sample
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
TestDemo obj=new TestDemo();
obj.disp("a");
obj.disp("a",2);
}}
Overriding : Here Methods can be over riding. It must be happen within two class. One is parent & another is child. In this parent class’s method with same name and signature.
public class TestDemo
{
public void eat()
{
System.out.println("Human is Eating");
}
}
class Overriding extends TestDemo
{
public void eat()
{
System.out.println("Human is Eating");
}
public static void main(String[] args)
{
Overriding obj=new Overriding();
obj.eat();
}
}
for more knowledge click on this link : https://arzatechs.com/overloading-and-overriding-in-java/
OVERLOADING:
Two or more methods with same name but different parameters in same class. The same as your question situation.
public void eat(int i,String s)
public void eat(String s, int i)
So, in your case it is method Overloading.
OVERRIDING:
Overriding means having two methods with the same method name and parameters (i.e., method signature). One of the methods is in the parent class and the other is in the child class.
ex.
class Animal{
void eat(){System.out.println("eating...");}
}
class Dog extends Animal{
void eat(){System.out.println("eating bread...");}
}
In this specific case, it's overloading.
Let's differentiate both terms a bit dipper:
Overloading (same function name but different signature):
Two or more methods having the same name with different arguments in
same class.
Overloading is used when you want to extend class functionality.
Overloading is is a compile time polymorphism.
Overriding (same function with the same signature):
Two or more methods having the same method name and same arguments in parent class and child class.
Overriding is used when you want to reuse the existing functionality.
Overriding is a run time polymorphism.
Visit to learn more about overloading and overriding.
Property ------------------- OverLoading -------------------- Overriding
Method Names -------------->must be Same--------------------> must be same
Arg Types------------------>must be Different(atleast arg)---->must be same(Including Order)
Method Signature----------->must be Different(atleast arg)---->must be same(Including Order)
Return Type---------------->No restriction------------------->No restriction
Private,Static,Final------->No Restriction-------------------->Must be Same
Access Modifyer------------>No Restriction--------------------Same
try/Catch----------------->No Restriction--------------------Exception Is thrown
Method Resolution-------->Compiler time (Reference)--------(JVM) Run Time Poymorphism

Categories