简体   繁体   中英

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

Methods get overriden during inheritance when they have the same signature. According to the docs signature depends on:

  1. the method name
  2. the number of the arguments
  3. 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

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?

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 ..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM