Java中的方法覆盖。为什么这个程序没有调用子类方法?

时间:2015-11-02 10:42:03

标签: java

为什么这个程序没有调用子类方法?它背后的概念是什么?我对此完全感到困惑。 以下是代码。

超级

public class TV {

     public void checkType(TV b) {
          System.out.println("Its a TV");
     }
}

儿童班

public class LedTv extends TV {

    public void checkType(LedTv b) {
         System.out.println("Its a LED TV");
    }

}

测试用例以获得结果

public class TestTV {

    public static void main(String argss[]) {
         TV a = new TV();
         TV b = new LedTv();
         a.checkType(a);
         b.checkType(b);

    }
}

两个checkType方法都打印

Its a TV
Its a TV

6 个答案:

答案 0 :(得分:3)

当继承具有相同签名时,方法会被覆盖。根据{{​​3}}签名取决于:

  1. 方法名称
  2. 参数的数量
  3. 参数的类型
  4. 在你的情况下这些方法

    public void checkType(TV b)
    public void checkType(LedTv b)
    

    显然有不同的签名,因为参数的类型不同。你得到的是方法重载

答案 1 :(得分:3)

public class LedTv extends TV {
    @Override //always put this here
    public void checkType() {//no need for argument
        System.out.println("Its a LED TV");
    }

}

从上面的例子可以看出,我添加了一个注释@Override。虽然这不是必要的,但它会强制编译器检查并确保您实际上覆盖了某些内容。如果你不是,你会得到一个错误,这有助于解决错误。我摆脱你传递给检查类型的论点的原因是因为它是多余的。您始终可以使用this关键字指向您当前所在的对象。

我意识到我忘了解释什么是覆盖和重载,所以我想这个例子会告诉你。

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");
     }
  }

}

输出

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

正如您在 SuperClass 中看到的那样方法() 重载,其中int为方法(int x) 方法()子类中被重写。在输出中,您可以清楚地看到最新情况。 What's the difference between overloading a method and overriding it in Java?

答案 2 :(得分:0)

重写方法必须具有相同的参数类型。如果要覆盖子类中的方法,它必须具有相同的参数,只有返回类型可以不同但是来自与超类方法相同的层次结构

答案 3 :(得分:0)

void checkType(TV)是与void checkType(LedTv)不同的函数原型。

因此,您不是重写,而是重载

对于覆盖,函数名称和参数类型必须相同,并且返回类型相关。关联性的确切定义超出了本问题的范围。

答案 4 :(得分:0)

你正在做方法重载。对于方法重写,父类和子类的方法签名应该相同。所以在子类而不是这个

public void checkType(LedTv b) {
     System.out.println("Its a LED TV");
}

输入并检查 -

public void checkType(TV b) {
     System.out.println("Its a LED TV");
}

答案 5 :(得分:-1)

因为您的两个对象都是TV类型。

TV a = new TV();
TV b = new LedTV(); 

基本上是相同的对象基类型。在创建b的情况下,您所做的只是告诉您想要具有子类功能的超类实例。你正在重载方法,而不是覆盖它们。你告诉程序参数是LedTV,打印出来,如果参数是TV,打印出来。您只是将if-else逻辑外包给程序本身。你做的是

if(TV == TV) print TV
else if (TV == LedTV) print LedTV

但问题是你的代码中的两个对象都是TV类型,因此总是使用超类方法,第一个if为true,第二个甚至没有被评估。

将b更改为:

LedTv b = new LedTv();
b.checkType(b);

它现在可以正常工作,因为b的类型为LedTV ..