I have started with JAVA programming recently and have one question to ask. Let's say I have one SuperClass and one SubClass which extends SuperClass and try to Override a method defined in SuperClass as follows:
public class SuperClass{
public void method1(int val){
System.out.println("This is method in SuperClass.Val is:" + val);
}
}
I try to extend the SuperClass in my SubClass and override the method with only one exception, instead of type int
declared in method1, I use the type for the argument as Integer
, as follows:
public class SubClass extends SuperClass{
@Override
public void method1(Integer val){ ///compiler gives an error
}
}
This declaration of SubClass method is not allowed by the compiler(I am using eclipse IDE). Why is this so? Integer is essentially wrapper of int then why such a declaration is prohibited?
Thanks
You can have multiple versions of a method with the same name having different number of parameters. You can have all these in the main/parent class or you can add the newer versions in the subclasses only. There is no restriction on doing this.
4) What happens if we change the arguments of overriding method? If we change the arguments of overriding method, then that method will be treated as overloaded not overridden.
Before JDK 5.0, it was not possible to override a method by changing the return type. When we override a parent class method, the name, argument types, and return type of the overriding method in child class has to be exactly the same as that of the parent class method.
Q. Why should a method be overridden in Java instead of writing a method with a different name? It is not possible to change the method calling code at all occurrences of the project. It may break the whole project.
The formal explanation, as you probably already understand, is that the two functions have different signatures, (as Andrew Tobilko has already pointed out,) so one may not override the other.
So, I presume that by asking this question, what you really mean to ask is "why is this so", or "why can't the compiler figure things out so as to allow me to do this".
So, the practical explanation is as follows:
This is because you may have some method somewhere, (of some unrelated class even) which accepts a SuperClass
as a parameter, and attempts to invoke its method1()
like this:
public void someMethod( SuperClass s )
{
s.method1( 7 );
}
When the compiler finds this, it will pass 7
as a parameter to method1()
, it will not pass a wrapped 7
. However, s
may not really be an instance of SuperClass
, it may be an instance of SubClass
, like this:
/* some code somewhere */
someMethod( new SubClass() );
This is valid because there is a principle in OOP known as the Liskov Substitution Principle which says that
if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.).
This is the same principle which allows you to assign a new ArrayList<String>()
to a variable of type List<String>
, and without it, nothing would work in OOP.
So, the compiler would have to pass a plain primitive 7
, but the receiving method of SubClass
would be expecting a wrapped 7
, and that would not work. So, the language stipulates that an implicit conversion of this kind is invalid, to ensure that nonsensical situations of this kind may not arise.
Amendment
You might ask, "why would it not work?" The answer is that primitives in java correspond to machine data types of the underlying hardware, while wrapped primitives are objects. So, on the machine stack, a 7
would be represented by a machine word with the value of 7
, while a wrapped 7
would be represented by something like 0x46d7c8fe
, which would be a pointer to an object which contains the wrapped 7
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With