Overloading overridden method in subclass, am I overloading parent method or sub-classes method?
I understand generally what overloading and overriding is.
Overloading - same method different parameters and maybe return type in the same class.
Overriding - in subclass same method signature as in parent but different implementation.
class A {
public void a() {
System.out.println("A.a");
}
}
class B extends A {
public void a() {
super.a();
System.out.println("B.a");
}
public void a(int x) {
}
}
Is method B.a(int x) overloading A.a or B.a?
You override something that is inherited, so B.a() overrides A.a(). Overriding means to redefine.
Overloading is when your class have more than one definition of the same method name (each with different argument types). In B, the name a is overloaded. There is B.a() and B.a(int x).
Some of the definitions might be inherited. So if you remove B.a(), the class B would still have a method a() since it inherits it from A. And the method name a would still be overloaded in B.
Method B.a(int x) overloads B.a(), since method overloading resolution takes place at compile time, and depends on the compile time type of the variable for which you are calling the method.
On the other hand, the decision of which overridden method to execute takes place at runtime, and depends on the run-time type of the instance for which you are calling the method.
You can see that by trying the following code, which won't pass compilation, since class A has no method of the signature a(int x):
A b = new B ();
b.a(4);
b.a(int x ) is overLoading a method of class B.a()
Rules of Overriding
Rule #1: Only inherited methods can be overridden.
Rule #2: Final and static methods cannot be overridden.
Rule #3: The overriding method must have the same argument list.
Rule #4: The overriding method must have the same return type (or subtype).
Rule #5: The overriding method must not have more restrictive access modifier.
It is overloading of subclass' method. That means B.a(int x) is an overloaded version of B.a().
Class A has not any method with the signature with public void a(int x). So it's overloading of B's method public void a().
Related
In Java,
Overloading is creating methods with the same name but different signature and Overriding is creating methods with the same name and the same signature.
So what happens, overloading or overriding, when we create a constructor in child class in JAVA?
Neither. Constructors are different from methods. You overload a constructor by writing multiple constructors in the same class, not in inherited classes. And constructors aren't subject to overriding. If I call new X("Hi"), I know I'm calling a constructor defined and implemented in X, not a constructor overridden in some subclass of X, or inherited from some superclass of X.
According to the JLS ยง8.8,
Constructor declarations are not members. They are never inherited and therefore are not subject to hiding or overriding.
So it's not overriding. And since constructors are not inherited, it's not overloading the constructor in the super either, when you declare a constructor in the subclass. It is however:
overloading other constructors declared in the same class, if any, or;
replacing the default constructors if no constructors have been declared before.
A class consists of members (fields or methods) and constructors - as entirely different things. But you want to do a conceptual comparison.
class A {
A() { }
}
class B extends A {
B() {
System.out.println("Bar");
}
}
Internally in the JVM (java virtual machine) the constructor signatures are A.<init>()
And B() is implemented internally as:
int field1;
String field2;
String field3 = null;
int field4 = 42;
B() {
// 1. Explicit or implicit super constructor:
super(); // A.<init>();
// 2. All fields with initialisation:
field3 = null;
field4 = 42;
// 3. The remaining code:
System.out.println("Bar");
}
This looks like overriding A.<init>() (though #Override is not allowed), but the base method is called implicitly (parameterless), or explicitly as super(...).
Overloading means having more than 1 constructor in B.
Does it represent both overriding and overloading at same time? in class B
public class A{
void someMethod(){
System.out.println("Class A's some method");
}
}
class B extends A{
void someMethod(){
super.someMethod(); // does this line reperesnt overloading of super class method??
System.out.println("Class B's some method");
}
}
There is no method overloading in this code snippet. Overloading occurs when two methods with a different list of arguments (either different number of arguments or different types of arguments) have the same name.
And the overriding occurs simply due to class B having a method with the same signature and access level as class A - someMethod(). It doesn't make a difference whether B's implementation of that method executes A's implementation (using super.someMethod()) or not.
Besides that Java inheritance is a fundamental feature of the language, I have some questions.
Here is the source for my testing example:
class MyClass{
public void say(String t){
System.out.println("Hello MyClass "+t);
}
public void print(MyClass t){
System.out.println("MyClass is printed");
}
public void anotherPrint(int i){
System.out.println("MyClass is printed again");
}
}
class MyClass2 extends MyClass{
public void say(String t){
System.out.println("Hello MyClass2 "+t);
}
public void print(MyClass2 t){
System.out.println("MyClass2 is printed");
}
public void anotherPrint(double i){
System.out.println("MyClass2 is printed again");
}
}
public class HelloWorld{
public static void main(String []args){
MyClass klass = new MyClass2();
klass.say("h"); //Question 1 (Prints: "Hello MyClass2 h")
klass.print(new MyClass2()); //Question 2 (Prints: "MyClass is printed")
klass.print(new MyClass()); //Question 3 (Prints: "MyClass is printed")
klass.anotherPrint(1); //Question 4 (Prints: "MyClass is printed again")
klass.anotherPrint(1.0); //Question 5 (Throws Exception!)
}
}
I have the following questions:
1. The klass object is instance of MyClass. Why does it execute the method from the MyClass2 class?
2,3 . At question 1 klass calls the method of the MyClass2 class. Here I used a parameter that fits to each one of the overridden and overloaded (simultaneously) methods. Why klass object always calls the method from the MyClass class?
4. It is normal. No question at all.
5. It is right to throw an exception. The klass object does not have this method with double parameter. But, why it is not called the method from the MyClass2 class, just like it happened at Question 1?
1. The klass object is instance of MyClass.
No it is a reference variable of type MyClass but referring to an object of MyClass2.
2. Why does it execute the method from the MyClass2 class?
Since you are invoking say() on an object of MyClass2, it executes the say() of MyClass2. Expected behavior.
This is called the run time polymorphism in Java. This provides the ability to override functionality already available in the class hierarchy tree. At run time, which version of the method will be invoked is based on the type of actual object stored in that reference variable and not on the type of the reference variable.
3. At question 1 klass calls the method of the Class2 class. Here I used a parameter that fits to each one of the overridden and overloaded (simultaneously) methods. Why klass object always calls the method from the MyClass class?
That is not overridden method. 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.An overriding method can also return a subtype of the type returned by the overridden method. This is called a covariant return type.Your method signatures are different. Hence invoking klass.print() where klass is a MyClass reference will always refer to the print() of MyClass.
4. It is right to throw an exception. The klass object does not have this method with double parameter. But, why it is not called the method from the MyClass2 class, just like it happened at Question 1?
Because at compile time, the compiler validates if you can call a method based on the reference type. Here the reference type is MyClass and since MyClass doesn't define anotherPrint(double), the compiler complains.It is a compile time check.In question 1, compiler verified klass.say("hi") and it saw that there exists a method in MyClass which can be invoked this way. At that time, it was not concerned whether klass reference variable will refer to a MyClass object or MyClass2 object at runtime. Hence it worked.
You can refer to these Oracle's tutorials here.
An instance of a class will have the methods of the father(s) plus its own methods. If the signature of one of the child class is the same than the signature of a method in the father, will override it.
In this example, an instance of MyClass2 will have this methods:
public void say(String t) //From MyClass2 (override)
public void print(MyClass2 t)
public void anotherPrint(double i)
public void print(MyClass t) //Inherited from MyClass
public void anotherPrint(int i) //Inherited from MyClass
But you are declaring klass as a MyClass, so it will have available this methods
public void say(String t) //From MyClass
public void print(MyClass t)
public void anotherPrint(int i)
Now, answering your questions
1 - You invoke the method say of a MyClass. But in runtime, actually klass is an object of MyClass2 and MyClass2 overrides this method, so it will invoke the one from MyClass2
2,3 - You invoke the method print of MyClass. In runtime, klass is from MyClass2, but MyClass2 IS NOT OVERRIDING THIS METHOD. The signature is different. So the one to be called is the MyClass. Works fine with a MyClass2 object as parameter since MyClass2 is a MyClass
5 - MyClass has not any method called anotherPrint receiving a double
Question 1:- With the line MyClass klass = new MyClass2(); you have done upcasting, catching the reference id(object) of child class. In case of upcasting, the methods of the child class are called.
Though the compiler checks for the say() function in the parent at comiple time but at run time compiler sees that we have say() function in child also, so it binds it with the child class method and calls it. This is the reason you are getting the output for Question 1 as Hello MyClass2 h
Method overloading and method overriding in Java is two important concept in Java which allows Java programmer to declare method with same name but different behavior. Method overloading and method overriding is based on polymorphism in Java. In case of method overloading, method with same name co-exists in same class but they must have different method signature, while in case of method overriding, method with same name is declared in derived class or sub class.Method overloading is resolved using static binding in Java at compile time while method overriding is resolved using dynamic binding in Java at runtime. In short When you overload a method in Java its method signature got changed while in case of overriding method signature remains same but a method can only be overridden in sub class. Since Java supports polymorphism and resolve object at run-time it is capable to call overridden method in Java
Read more: http://javarevisited.blogspot.com/2011/12/method-overloading-vs-method-overriding.html#ixzz34EEhLp2u
I have a code and I am not able to get why the output will be "Radial Tire with long".Can somebody help me to understand this code?
class Tyre {
public void front() throws RuntimeException {
System.out.println("Tire");
}
public void front(long a) {
System.out.println("Radial Tire with long");
}
}
class TestSolution extends Tyre {
public void front() {
System.out.println("Radial Tire");
}
public void front(int a) throws RuntimeException {
System.out.println("Radial Tire with int");
}
public static void main(String... args) {
Tyre t = new TestSolution();
int a = 10;
t.front(a);
}
}
front is not overridden in TestSolution, it is overloaded.
You can regard an overloaded function as a completely different function, like one with a different name.
So t.front(a) will call the one in Tyre, with an a implicitly converted to long.
So if we go with definitions
Overloading means methods with same name but with different number or order of parameters.
Overriding means method with same name with same number of parameters along with rules mentioned here
So in your case front method is overloaded in both the classes Tyre and TestSolution
method front() from Tyre class is overridden in class TestSolution.
no overriding in case of method front(long a) and front(int a).
There's no overriding taking place in your main.
t's static (compile-time) type is Tyre, so, since method overload resolution is determined by the compile-time type of the instance, the only front methods available for the compiler to choose from are those declared in the base class Tyre :
public void front()
public void front(long a)
Only the latter (public void front(long a)) matches the arguments of the call t.front(a), and that method is not overridden by the sub-class. Therefore Radial Tire with long is displayed.
Calling ((TestSolution)t).front(a); would invoke the sub-class's method - public void front(int a).
General rule: if I have a variable of one class I can access only methods and components defined in that class.
The only particular case is:
you have a component or method both in the super class and in the subclass (overriding)
you have a variable of the super class and an object of the subclass (your case)
In these cases you can follow the following rule:
for the components the type of the variable decides which to use
for the methods the type of the object does (late binding)
In your case as stated before the method is not overridden so you can't apply the last rule.
Lets understand the difference between overloading and overriding
Overloading:
The Java programming language supports overloading methods, and Java can distinguish between methods with different method signatures. This means that methods within a class can have the same name if they have different parameter lists
Overriding:
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.
Tyre declared front() method with long as parameter.
TyreSolution declared front() method with int as parameter.
Since the method signature is different, TyreSolution overloads Tyre's front() method
If you change signature of front() in TyreSolution to accept long value as input parameter instead of int, then TyreSolution overrides Tyre's front() method.
e.g. TestSolution class definition of front() method
public void front(long a) throws RuntimeException {
System.out.println("Radial Tire with long in TestSolution");
}
output:
Radial Tire with long in TestSolution
Let's have this method in parent class:
public void calculateSum(int a, final int b) { }
And the child class has:
public void calculateSum(int a, int b){ }
So is it method overloading or method overriding?
It's overriding, as the number and type of parameters are the same.
Overloading is when the type or number of parameters changes.
The final on the method parameter just instructs the compiler that the variable value (or reference) shouldn't be changed inside the method... this also affects the runtime, as final variables are published safely.
The child class method is overriding the parent class method. The child class method doesn't define a new set of arguments. The 'final' modifier doesn't affect argument type, just if it can be assigned a new value.
If method signature(which include method name and parameter list) is same along with return type(Assignment Compatible) then it's called overriding. Adding modifier to the parameter does not change the parameter type. So your answer is overriding.