Guys I know this question is silly but just to make sure:
Having in my class method:
boolean equals(Document d)
{
//do something
}
I'm overloading this method nor overriding right? I know that this or similiar question will be on upcoming egzam and would be stupid to not get points for such a simple mistake;
Based on the code provided, we can't tell for sure whether you're overloading or overriding it.
You are most likely overloading the equals(Object o) method.
class A {
void method() {..}
}
class B extends A {
// this is overriding
void method() {..}
}
And
// this is overloading
class A {
void method(boolean b) {..}
void method(String arg) {..}
void method(int arg) {..}
}
P.S. you are using a bracket convention that is not widely accepted on the java world. In Java it is more common to place opening the curly bracket on the same.
You are not even overloading, since the other method is called equals. But if you add that s, you will be overloading equals. Although, to be precise, we talk about overloading if two (or more) methods with the same name but different signature are defined in the same class. In your case, it is trickier, since your equals with its different signature partly hides the original equals. Which is usually a bad thing, because this almost always leads to hard to understand behaviour, thus subtle bugs. Whenever someone calls equals on an instance of your class, depending on the parameter type the call may go to a different implementation of the method.
class Document {
public boolean equals(Document d)
{
//do something
}
}
Document doc1 = new Document();
Document doc2 = new Document();
String string = new String();
doc1.equals(doc2); // calls Document.equals
doc1.equals(string); // calls Object.equals!
You would be overriding Object.equals if you defined your method with the exact same signature as the original, i.e.
public boolean equals(Object obj) ...
In this case, both of the above calls to equals correctly execute Document.equals.
From the code you posted it could be either. If equal is defined in a superclass with the same parameter declarations then you are overriding it. If there is already a method called equal, but with different parameter types, you are overloading it.
On a related note, if you are using Java 5 and above and your intent is to override then it is highly recommended to use the #Override annotation before the method definition to indicate your intention. The wrong usage of this annotation (i.e. when you want to override and are not doing so) would flag a compile error.
As of Java 6 you can use the #Override annotation while defining methods that are
declared in an interface the class in implementing.
Overloading: same method name, same parameter list, different classes
Overriding: same method name, different parameter list, same or different classes.
Class A {
bool Equals(Document d) {...}
bool Equals(A a) {...} // overloaded method
}
Class B extends A {
bool Equals(Document d) {...} // overridden method
bool Equals(B b) {...} // overloaded method
}
One thing to note, the return type does not matter, it's the name of the method and the parameter list that make all the difference.
Related
To clarify- To my understanding, the methods below are all override of Object.equals. Are they overloading instead and I am not understanding this correctly?
I'm running this code:
public class AA
{
private int _val=0;
public AA()
{
_val=5;
}
}
public class BB extends AA
{
public BB()
{
....
}
public boolean equals(BB ob)
{
return false;
}
public boolean equals(Object ob)
{
return true;
}
public boolean equals(AA ob)
{
return true;
}
public static void main(String args[])
{
AA a2=new BB();
BB b1=new BB();
if((a2.equals(b1)))
System.out.println("hi");
}
}
Class AA does not have an equalsmethod
I'm trying to figure out with the second method is triggered and not the first one. My understanding is:
Since class AA does not have an equals method, I suppose that at
compile-time the compiler wants to run the equals from Object
class.
At run time the compiler finds out that a2 is actually a BB object
and therefore has equals methods that override the method from
Object.
However, what is not clear to me is why the second method (Object ob) is chosen instead of the first (BB ob), if the sent object is defined and actually is a BB object.
Would appreciate your feedback!
When you call a.equals(b), the compiler looks at the equals methods in AA. If it found an appropriate one there, it would use it. In this case, AA has no methods called 'equals'. So it steps up the inheritance chain, and looks again. This time, it is looking at Object, and it finds Object.equals(Object). At runtime, it finds the most overridden version and calls it.
So if it's still just looking for a method called 'equals', why doesn't it find the more specific version equals(BB) at runtime?
BB.equals(BB) is not considered an override of Object.equals(Object). It has a more specific parameter, and can't handle a plain Object. Imagine the types are part of the name:
equals_Object
equals_BB
The compiler picked the equals_Object method, so at runtime the JVM will not find the equals_BB method, because it isn't looking for it.
Overloads are not chosen at runtime, they're chosen at compile time, when the compiler only knows that the object is an AA. Only overrides are chosen at runtime, based on the actual runtime type of the object, but the overload selected at compile time is still used.
I know that a method can be overriden with one that returns a subclass.
Can it also be overloaded by a method which returns a subclass?
public Object foo() {...}
public String foo(int a) {...}
Is the above code valid?(if placed within a Class)
What about?
public Object foo() {...}
public String foo() {...}
Beginning with Java 5, covariant return types are allowed for overridden methods. This means that an overridden method in a subclass is allowed to use a signature which returns a type that may be a subclass of the parent signature's return type.
To make this concrete, say you have this interface:
public interface MyInterface {
Number apply(double op1, double op2);
:
:
}
The following is legal because the return type is a subclass of Number:
public class MyClass implements MyInterface {
:
:
#Override
public Integer apply(double op1, double op2) {
:
:
return Integer.valueOf(result);
}
}
Because overloaded methods (which have the same name but different signatures) are effectively different methods, you are free to use different return types if you like ... however ... this is discouraged because methods that have the same name but different return types can be confusing to programmers and can complicate the use of your API. It's best not to overload mrthods when you can reasonably avoid it.
This example:
public Object foo() {...}
public String foo(int a) {...}
as long as the two methods get different set of variables, there's no problem with returning different types (even if they are not subclass).
The logic is very simple - if the compiler can choose without doubt which one to use - there's no issue. In this case- if you give the method int it's one method, and without parameters it's the other, no dilema (and the same name does not matter here)
as for:
public Object foo() {...}
public String foo() {...}
This one is not valid, since here the compiler can't 'choose' which one to use.
Yes, and it does not even need to be a subclass foo(), and foo(int) are two completely different and unrelated functions as far as the compiler is concerned, each can have any return type you want.
yeah, you overroad foo with foo(int a) , and gave it a new data type String , the compiler see this as a valid code but the other one Object foo() and String foo() is totally invalid in java
In overloading when we overload a method why we cant make a new method which works same as overloaded method because we have to write the same number of line of code Such as in my example...why i cant make a new method b() which multiply two numbers.
public class que {
public void a(int a)
{
System.out.println(a);
}
public void a(int b,int c) {
System.out.println(b*c);
}
public static void main(String[] args) {
que queObject = new que();
queObject.a(5);
queObject.a(3,4);
}
}
You can make all your methods have different names. The point is you don't have to. This reduces the number of names a developer using the API needs to learn.
e.g. in the PrintWriter you have lots of methods called print and println which conceptually all do the same thing. They could have been given different names, but then you would need to know which method you wanted to call,
At runtime, each method signature is unique as it includes the return type and the non generic argument types form. i.e. in byte code the names are made unique for you.
In Java, a method cannot be distinguished/overloaded by it's return type, though in Java 6 there was a bug which allowed overloading on methods with different return types.
Nobody says you can't do this. It just isn't method overloading. That's defined as two or more methods of the same name, but with different (parameter) signatures.
method name signifies what a method does. so if you have 2 methods having same name but expects different arguments. its beneficial for the understanding of code and better design to have the same name.
so if you add another method
public void a(int b,int c,int d) {
System.out.println(b*c*d);
}
you basically doing the same behaviour i.e. multiplication but with more arguments. so overriding is better for understanding and good coding principles.
Consider This
public void eat(Orange o) {
// eat Orange
}
public void eat(Mango m) {
// eat Mango
}
You want different implementation on the basis of what you pass as a parameter but want to keep method name same.
For More Info --> Polymorphism vs Overriding vs Overloading
Here's my explanation:
public class Calculator {
// used for integer numbers
public int sum(int a, int b) {
return a + b;
}
// used for double numbers
public double sum(double a, double b) {
return a + b;
}
}
In this case you don't care if you use sum method with int or double - sum method is overloaded, so it will take both int and doubles. It's much easier than using sumInts() and sumDoubles() separately.
Method overloading is when, in a class, there are more than one method with same name but different arguments although it can have different return types (different return types is in itself is not a distinguishing feature and if only that is changed will result in a compile error).
For a complete discussion, see: http://beginnersbook.com/2013/03/polymorphism-in-java/
Why do we need it?
An example will be enlightening: Lets take the ubiquitous StringBuilder class and its append methods. They are a prime example of overloading. A specific instance of method overloading is constructor overloading as well. See the StringBuilder again: http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html.
As another example suitable to your case: we can have an appendBoolean(boolean b) and a appendString(String b) and a appendChar(char c) in the StringBuilder class as well. It is a matter of clarity and choice to either have that or just have a set of overloaded append methods. To me - since the operation is to append but we are appending different instance types - having an overloaded append makes sense and provides clarity and is concise. On the other hand, you have no such choice for overloaded constructors: they need to have the same name as the class - that is by convention and by design :-)
If I have the following code in Java:
class A {
public int add(int a , int b) {
return (a+b);
}
}
class B extends A {
public float add(float a , float b) {
return (a+b);
}
In this particular case the sub-class isn't exactly overriding the base class's add function as they have different signatures and the concept of overloading occurs only if they are in the same scope. So, is the function add(float , float) in the sub-class B treated as an entirely new function and the concept of overloading and overriding is not applicable to it? And does it use 'Static binding' or 'Dynamic Binding'?
Method add in class b is an overload of add in class a. Not an override. An override would just be a different implementation of the original add method.
In brief, yes. To override, you need to replicate the complete method signature, which includes the method name, parameters and return types. From the tutorial
An instance method in a subclass with the same signature (name, plus
the number and the type of its parameters) and return type as an
instance method in the superclass overrides the superclass's method.
You might want to consider the #Override annotation, which will trigger a compiler error if you don't successfully overrride a method.
In this particular instance, it perhaps looks like you don't need overriding so much as some solution including generics. So you could instantiate a class a<Integer> and a similar class a<Float>
In that case you are not overriding the method, since the signatures are different.
But there is overloading in class b, since you have two methods with the same name but different parameters (one if class a, and the other one in class b)
Hope it helps.
There can be a method that is not overridden but overloaded in the subclass. Here the subclass has two add() methods. The version which accepts int arguments(not overridden), and the overloaded method add() which accepts float arguments.
I think in this particular case neither overloading nor overriding occurs, because return type must be same in case overloading and overriding, so neither static binding nor dynamic binding happens in this case.
method overloading is not possible in case of different return type, because compiler can't figure that which method he need to call.
I know it's late answer but i think it's important question need to be answered for beginners.
One key point in overloading is it works in inheritance.
Next is either it's Static binding or Dynamic binding.
It is Static Binding So, why?
Static Binding
Static binding in Java occurs during Compile time.
private, final and static methods and variables uses static binding and bonded by compiler.
Static binding uses Type (class in Java) information for binding.
Dynamic Binding
Dynamic binding occurs during Runtime.
Dynamic methods bonded during runtime based upon runtime object.
Dynamic binding uses Object to resolve binding.
But the important part is here
Overloaded methods are bonded using static binding while overridden methods are bonded using dynamic binding at runtime.
Java compiler determines correct version of the overloaded method to be executed at compile time based upon the type of argument used to call the method and parameters of the overloaded methods of both these classes receive the values of arguments used in call and executes the overloaded method.
B a=new B();
a.add(4, 5);
a.add(4.0f, 5.0f);
So if you will create reference of type B then it will search for proper argument type
and for above code it will execute both methods.
A a=new B();
a.add(4, 5);
a.add(4.0f, 5.0f);
but for above code it will give compile time error for float arguments.
Hope it clears all doubts.
First things first
Is it method overriding ?
No , since to override a method you need to replicate the complete method signature as pointed out in Brian Agnew's answer and as I explain below.
Is it overloading ?
Yes , Method "add" has an overloaded implementation in Class B.
Consider the following code:
class C{
public static void main(String args[]){
B a = new B();
a.add(2 , 3);
a.add(2.0 , 3.0);
}
}
class A {
public int add(int a , int b) {
System.out.print("INT ");
return a + b;
}
}
class B extends A {
public double add(double a , double b) {
System.out.print("Double ");
return a + b;
}
}
OUTPUT : INT Double
So , the method in Class B in your code overloads the add method that it inherits from its parent
Does it use Static Binding or Dynamic Binding ?
This is what makes me conclude that OP is confused.It is static binding because it is a overloaded function. The only way to think of dynamic binding would have been in below scenario
class C{
public static void main(String args[]){
A a = new B();
a.add(2.0 , 3.0);
}
}
class A {
public int add(int a , int b) {
System.out.println("A : INT");
return a + b;
}
}
class B extends A {
public int add(int a , int b) {
System.out.println("B : INT");
return a + b;
}
public double add(double a , double b) {
System.out.println("Double");
return a + b;
}
}
Output : B : INT
Here , the parent class A has a contract that says , "I have an add behaviour for ints" . class B inherits this add behaviour and makes it more specific and at the same time also provides a new behaviour where it can add doubles.
But class A has "no knowledge of this behaviour".
So an object of class A "cannot" add doubles. To do that you need a more specific type of A object i.e. a B object.
The method add() in class A is also available to class B by inheritance, therefore the method is overloaded in class by changing the data type from int, int to float, float.
The concept of Overloading comes in play if and only if the functions are in the same scope or class.
cz if this is the case of method overloading then for same method signature or same argument type the compiler gets confuse and must give compile time error .
but in the above program in class B if you pass the same argument in same order then according to overloading it must give error but it is not happening u can check it i already have.
It is the case of inheritance where through object reference if you call any method then the compiler will check it in child class ,if its not there then it will look into parent class that the above program is all about.
hope this is helpfull.
class Super {
public void anotherMethod(String s) {
retValue(s)
}
public String retValue(String s) {
return "Super " + s;
}
}
class Sub extends Super {
public void anotherMethod(String s) {
retValue(s)
}
public String retValue(String s) {
return "Sub " + s;
}
}
if suppose in main,
Super s = new Sub();
s.anotherMethod("Test");
Output will be, Sub Test
Can you anyone help me in telling how to get output Super Test with the given sequences in main.
And let me explain why I want this, say I have a class which has method test() and it can be overriden by sub classes, in some cases I want the overriden test() and in some cases I want the test() of super class itself, there are many ways to do this, best suggestions will be helpful.
Why would you ever want to do that ??
The whole point of polymorphism is to call the right method without the need to know which kind of instance you've got ...
Whenever I find myself asking (or being asked) a question like this, I know, categorically, that I have made a mistake in my design and/or my object definitions. Go back to your object hierarchy and check, double-check and triple-check that every inheritance relationship represents an "IS-A", and not a "HAS-A" or something even weaker.
And let me explain why I want this,
say I have a class which has method
test() and it's can be overriden by
sub classes, some cases I want the
overriden test() and in some cases
test() of super class itself, there
are many ways to do this, it will be
helpful if anyone can be best
solution.
If your subclass overrides test(), then it overrides test() - this is the whole point of object inheritance. You just call methods on the object, which are dynamically resolved to the appropriate implementation based on the object's runtime class. That's the beauty of polymorphic typing, in fact, the caller doesn't have to know about any of this at all, and the subclasses determine how their behaviour differs from the superclass.
If you sometimes want it to act as its superclass method and sometimes want it to act as its subclass method, then you need to provide the context required to do this. You could either define two test-type methods; one which is never overridden and so always returns the superclass' behaviour (you can even mark the definition with final to ensure it's not overridden), and your normal one which is overridden as appropriate by the subclasses.
Alternatively, if there is some contextual information available, you can let the subclasses decide how to handle this; their implementation(s) could check some proeprty, for example, and based on that decide whether to call super.test() or proceed with their own overridden implementation.
Which one you choose depends on conceptually whether your main method (i.e. the caller), or the (sub)class objects themselves, are going to be in the best position to judge whether the superclass' method should be called or not.
But in no case can you override a method and expect it to magically sometimes not be overridden.
You would have to go the route of:
Super s = new Super();
s.anotherMethod("Test");
...but that will defeat the purpose of inheritance if you also need whatever Sub's got. You could hack it like below but this seems an unelegant way to do it.
class Sub extends Super {
public String anotherMethod( String s, boolean bSuper ) {
if( bSuper )
return super.retValue(s);
else
return retValue(s);
}
public String retValue(String s) {
return "Sub " + s;
}
}
From class Sub you can call super.anotherMethod("bla"), but you cannot access the method of the superclass in your main method - that would be against the whole idea of using subclasses.
The runtime type of s is Sub, so you're only ever calling methods on that class.
Whilst I agree with the other posters that this is not the best idea in the world, I believe it could be done with a little bit of tinkering.
If your child class was defined as:
class Sub extends Super {
public void anotherMethod(String s) {
retValue(s)
}
public void yetAnotherMethodString s) {
super.retValue(s)
}
public String retValue(String s) {
return "Sub " + s;
}
}
and then call this new method in your main you would be able to print out "Super Test".
Doesn't seem like a very good plan tho. If you want access to parent functionality from a child class then don't override your parent method, just write a new one!
I'm hesistant to post this as an answer, since the question is quite horrible - but static methods would do roughly what the OP seems to want. Specifically, they are resolved on the compile-time declared class of the variable, not on the class of the instance held within that variable at runtime.
So modifying the original example:
class Super {
public static void staticMethod(String s) {
System.out.println("Super " + s);
}
}
class Sub extends Super {
public static void staticMethod(String s) {
System.out.println("Sub " + s);
}
}
public static void main(String[] args) {
Super s = new Sub();
s.staticMethod("Test");
}
then main() will print out "Super test".
But still don't do this until you understand why you want to, and you recognise that you are introducing subclasses and then gratuitously working around the point of them being there. Most IDEs for example will flag the above example with lots of warnings, saying that you shouldn't call static methods on instance variables (i.e. prefer Super.staticMethod("Test") instead of s.staticMethod("Test")), for exactly this reason.
You cannot modify Sub or Super directly? If you could control what instance of Sub is used you could do something like:
Super sub = new Sub() {
#Override
public String retValue() {
// re-implement Super.retValue()
}
};
otherObject.use(sub);
Of course this requires you to have or be able to reproduce the source code of Super.retValue() and for this method not to use anything you can't access from an anonymous child. If the API is this badly designed though, you might do well to think about changing it out for something else.
Can you anyone help me in telling how
to get output "Super Test" with the
given sequences in main.
Don't overwrite anotherMethod() and retValue() in Sub in the first place.
In Sub.anotherMethod(), return super.retValue(s) instead of retValue(s).