why it is printing Integer - java

why it is printing Integer?
At the time of compilation, the method call bound to class A's method.
I hope in B I am not overriding. creating a other method means method overloading with different classes.
but what is happening at run time?
class A{
void method(Integer i)
{
System.out.println("Integer");
}
}
class B extends A
{
void method(int i)
{
System.out.println("Int");
}
}
public class Puzzle{
public static void main(String ar[]){
A a = new B();
a.method(20);
}
}

B has two different methods called method: one declared by A, which is method(Integer), and one declared by B, which is method(int).
Since your variable a is of type A, a call to a.method() must refer to a method provided by class A, which is method(Integer).

Your methods don't share the same signature.
void method(int i) is not equal to void method(Integer i) - the first one uses primitive type. Second one uses Object Integer.
If you change method in A to method(int i) you can then override the method of A, so in your subclass:
#Override
void method(int i)
{
System.out.println("Int");
}

B doesn't override the method called "method" because it is not the same type of parameter of your method in A (Integer).
int is a primitive type while Integer is a class.
B method should be :
#Override
void method(Integer i)
{
System.out.println("Int");
}
The annotation #Override is here to tell the class should override a method. It is a good practice but not necessary (I would work without it). If you put it with your current code you would have an error because method doesn't override any method.
I hope it will help you.

This is exactly what #Override annotation is for - add #Override when you think you're overriding and the compiler will tell you if you're wrong in thinking so.
If you add #Override to the B's method(int i), the compiler will give you an error telling you that you're not in fact overriding it, because the signatures differ - namely the method has different parameter type that's not a superclass of parent's parameter type.

The signatures of the method of A and that of B are not the same. The method in A takes an object integer (Integer) as parameter while that of B takes a primitive integer (int) as parameter. So you are not really overriding the method of A in B. To do so, change the signature of the method B to be like that of A.
class A{
void method(Integer i){
System.out.println("Integer");
}
}
class B extends A{
#Override
void method(Integer i){
System.out.println("Int");
}
}
public class Puzzle{
public static void main(String[] args){
A a = new B();
a.method(20);
}
}

Your reference is of type A - it does not recognize methods declared in type B in compile time, even though the may exist in runtime. The int literal 20 is then autoboxed to a java.lang.Integer, and method(Integer) is called.
If you were to declare the reference as B, the method(int) would be a better fit to your argument, and would be have been called.

Related

Which method is chosen in a polymorphism when calling a method available in the parent and the child class?

I don't understand why the ab.m3() method calls the function of the parent class and not the child. I thought maybe passing a new Integer to the method might call the method of the parent class because Integer is an Object so I tried it with an int but still it gave me the same result!
public class A {
public void m1(){
System.out.println("A.m1");
}
public void m2(){
System.out.println("A.m2");
}
public void m3(Object x){
System.out.println("A.m3");
}
}
public class B extends A{
public void m1(){
System.out.println("B.m1");
}
public void m2(int x){
System.out.println("B.m2");
}
public void m3(int x){
System.out.println("B.m3");
}
public static void main(String[] argv){
A aa = new A();
A ab = new B();
int num = 2;
ab.m1();
ab.m2();
ab.m3(new Integer(2));
ab.m3(num);
}
}
Output:
B.m1
A.m2
A.m3
A.m3
B.m3 does not override A.m3, because the parameter lists are not compatible.
Because the only matching method in A is A.m3, and because there is no override in B, it is A.m3 that will be called.
Your ab reference is of type A.
When compiling ab.m3(num);, the compiler isn't looking at the object type. In general, it won't always know what the object type is. Instead, it's looking at the reference type. It cannot match B.m3(int), because the reference type is not of type B.
So the compiler chooses the A.m3(Object) method, which could be overridden at runtime. But it's not, so the A implementation is called.

Method overriding in Java. Why is this program not calling the sub class method?

Why is this program not calling the sub class method? What is the concept behind it? I'm totally confused with this.
Below is the code.
Super class
public class TV {
public void checkType(TV b) {
System.out.println("Its a TV");
}
}
Child class
public class LedTv extends TV {
public void checkType(LedTv b) {
System.out.println("Its a LED TV");
}
}
Test case to get the result
public class TestTV {
public static void main(String argss[]) {
TV a = new TV();
TV b = new LedTv();
a.checkType(a);
b.checkType(b);
}
}
Both of the checkType method prints
Its a TV
Its a TV
public class LedTv extends TV {
#Override //always put this here
public void checkType() {//no need for argument
System.out.println("Its a LED TV");
}
}
As you can see from the above example I added an annotation #Override. While this isn't necessary it forces the compiler to check and make sure you are actually overriding something. If you are not you will get an error, which helps solve bugs. The reason I got rid of the argument that you are passing to check type is because it's redundant. you can always use the this keyword to point to the object you are currently inside of.
I realise I forgot to explain what overriding and overloading is so I think this example will show you.
public class Main{
public static void main(String[] args){
new Main();
}
Main(){
new SuperClass().method();
new SuperClass().method(101010);
new Subclass().method();
new Subclass().method(595959);
}
class SuperClass{
SuperClass(){
System.out.println(this.getClass().getSimpleName());
}
public void method(){
System.out.println("method() from SuperClass -> Calling method(int x)");
method(0);
}
public void method(int x){
System.out.print("method() from SuperClass " + x + "\n\n");
}
}
class Subclass extends SuperClass{
#Override
public void method(int x){
System.out.print("method() from SubClass " + x + "\n\n");
}
}
}
Output
SuperClass
method() from SuperClass -> Calling method(int x)
method() from SuperClass 0
SuperClass
method() from SuperClass 101010
Subclass
method() from SuperClass -> Calling method(int x)
method() from SubClass 0
Subclass
method() from SubClass 595959
As you can see in SuperClass method() is overloaded with an int as method(int x) and method() is overridden in Subclass. In the output you can clearly see whats going on. What's the difference between overloading a method and overriding it in Java?
Methods get overriden during inheritance when they have the same signature. According to the docs signature depends on:
the method name
the number of the arguments
the type of the arguments
In your case these methods
public void checkType(TV b)
public void checkType(LedTv b)
Clearly have different signatures as the type of the argument is different. What you get is called method overloading
overriding method must have the same types for arguments. If you want to override method in subclass it must have the same arguments only return type can be different but from the same hierarchy as in superclass method
void checkType(TV) is a different function prototype to void checkType(LedTv).
Therefore you are not overriding, but rather you are overloading.
For overriding, the function name and parameter types must be identical, and the return type related. The exact definition of relatedness is beyond the scope of this question.
You are doing method overloading. For method overriding both the method signature of the parent and child class should be same. So in the child class instead of this
public void checkType(LedTv b) {
System.out.println("Its a LED TV");
}
type this and check -
public void checkType(TV b) {
System.out.println("Its a LED TV");
}
Because both of your objects are of type TV.
TV a = new TV();
TV b = new LedTV();
is basically the same object base type. In case of creating b, all you do is basically telling you want superclass instance with the sub-class functionality as well. And you are overloading the methods, not overriding them. You tell the program if parameter is LedTV, print out this, if parameter is TV, print out this. You are outsourcing the if-else logic to the program itself, simply. What you do is
if(TV == TV) print TV
else if (TV == LedTV) print LedTV
But the problem is both objects are of type TV in your code, so the superclass method is always used and the first if is true, and second one is not even evaluated.
Change b to this:
LedTv b = new LedTv();
b.checkType(b);
It will now work correctly, because b is of type LedTV..

Overloading via Overriding

Why overloading is not happening here even though passing integer argument to method "p" . ?
public class Test {
public static void main(String[] args) {
B a = new A();
a.p(10);
a.p(10.0);
}
}
class B {
public void p(double i) {
System.out.println(i * 2);
}
}
class A extends B {
// This method the method in B
public void p( int i) {
System.out.println(i);
}
//added below code
public void p( double i) {
System.out.println(i*5);
}
}
Output:50.0
50.0
Because the variable a is declared as B, only the p method declared in B is visible and thus chosen. There's no overriding involved.
When in doubt, annotate your method with #Override in your favorite IDE. The IDE won't let it compile if it's not actually overriding anything.
After your edit, you now have an overriden method in the form of A#p(double). When you invoke
a.p(10);
a.p(10.0);
The method p visible on the B class will be invoked. Through polymorphism and because the variable a is of run time type A, the overriden method declared in A will be invoked.
Note that the int argument in
a.p(10);
becomes a double through widening primitive conversion.
Because you're invoking things through a reference-to-a-B. That only has one method.
It's always calling the method in B, because:
the variable is of type B, so the compiler only knows about the double method
the method in A does not override B's method because the parameter type int is different from B's double - it's invisible to the calling code

Java Casting with Method Calls

Suppose I have the following classes
class A{
public method(A a) {
System.out.println(3);
}
}
class B extends A{
public void method (A a) {
System.out.println(2);
}
public void method (B b) {
System.out.println(1);
}
}
A obj = new B();
obj.method( (B) obj);
((B) obj).method( (B) obj);
The first method call prints out 2 while the second method call prints out 1. Why don't both method calls print out 1?
void method (B b) of B is totally unknown for its parent A.
It's logical, because in obj.method((B) obj);, the type of obj is A which in polymorphism rule it can just call void method(A a) version of class B.
class B extends A {
// This is an overridden method visible to A
public void method(A a) {
System.out.println(2);
}
// This is an overloaded method unknown from A
public void method(B b) {
System.out.println(1);
}
}
You can read this SO answer which explained Override vs. Overload.
Because java selects the method to call in compile time. And the compiler only take into account the "left side" of an assignment.
So when you type A obj = new B() the compiler only "sees" the methods in class A.
The first method call is done using object reference of type A, so the corresponding method, which could be overridden, is called.
In the second case first the cast is done to type B, so corresponding method defined in class B ,i.e,
method (B b)
is called.

What is the wrong with this java code?

I am learning java. The book I'm reading has a question which asks what is wrong with the following code? I have typed the code in NetBeans and I can see the error but why is this error caused and how is it resolved?
The error is highlighted over the code public A(int t) and it says
Constructor B in class B cannot be applied to given types, require int, found no arguments, reason actual and formal arguments lists differ in length.
Here is the code:
public class Test {
public static void main(String[] args) {
B b = new B(5);
}
}
class A extends B {
public A(int t) {
System.out.println("A's constructor is invoked");
}
}
class B {
public B(int k) {
System.out.println("B's constructor is invoked");
}
}
when your super class has an args constructor and doesn't have a no-args constructor you have to explicitly invoke it using a super(args) call from sub-class constructor
class A extends B {
public A(int t) {
super(t);
System.out.println("A's constructor is invoked");
}
}
Class B has defined constructor, so it does not have public implicit default constructor (with no arguments). All subclass constructors have to explicitly call superclass constructors, via super(t), if zero argument superclass constructor is not available.
The class B has only one constructor which takes an int argument. On the other hand, the constructor you have in class A (implicitly) tries to call a constructor in A's super class (namely B) that takes no arguments. This is the cause of the error. There are at least two ways to fix the problem:
Create a no-arg constructor in class B.
Explicitly call the constructor in class B which takes an int as a parameter. You can do this using the super keyword.
You need to call the constructor of the super class as the first statement in A(int):
public A(int t) {
super(t);
System.out.println("A's constructor is invoked");
}

Categories