Java 方法重写。为什么这个程序不调用子类方法?
为什么这个程序不调用子类方法?它背后的概念是什么?我完全不明白这一点。 下面是代码 超级级Java 方法重写。为什么这个程序不调用子类方法?,java,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.prin
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
重写方法的参数类型必须相同。如果要重写子类中的方法,它必须具有相同的参数,只有返回类型可以不同,但与超类中的相同层次结构。方法
无效检查类型(TV)
是与无效检查类型(LedTv)
不同的函数原型
因此,您不是在重写,而是在重载
对于重写,函数名和参数类型必须相同,并且返回类型必须相关。关联性的确切定义超出了这个问题的范围。当方法具有相同的签名时,它们会在继承过程中被重写。根据签名,签名取决于:
public void checkType(TV b)
public void checkType(LedTv b)
很明显,由于参数的类型不同,签名也不同。得到的称为方法重载,因为两个对象都是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,第二个if甚至没有计算
将b改为:
LedTv b = new LedTv();
b.checkType(b);
它现在可以正常工作,因为b
属于LedTV
类型
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。虽然这不是必需的,但它会强制编译器检查并确保您实际上正在重写某些内容。如果你不是,你会得到一个错误,这有助于解决错误。我之所以去掉传递给check type的参数,是因为它是多余的。始终可以使用关键字指向当前所在的对象
我意识到我忘了解释什么是重写和重载,所以我想这个例子会告诉你
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
正如您在超类中所看到的那样,方法()被int重载,因为方法(intx)和方法()在子类中被重写。在输出中,您可以清楚地看到发生了什么 您正在执行方法重载。对于重写父类和子类的方法签名都应相同的方法。所以在儿童班而不是这个班
public void checkType(LedTv b) {
System.out.println("Its a LED TV");
}
键入此项并检查-
public void checkType(TV b) {
System.out.println("Its a LED TV");
}
因为它没有被覆盖,所以它被重载了。您正在将
TV
类型的变量传递给该方法,因此它调用checkType(TV b)
。但是为什么第二个checkType()方法会打印它的a TV呢?因为变量b
的类型是TV
,而不是LedTV
(即使它引用了这样的对象,但这并不重要).那么您是说参数在需要调用哪个方法中没有作用?@BhajjiMaga他是说您不传入对象,因为这是上下文(this
)。查看您的呼叫a.checkType(a)
,其中您将给出a
两次。它应该是a.checkType()
,带有这个答案中的代码。@BhajjiMaga没有必要。“this”关键字指向自身。也许你可以在上面找到其他资源。我添加了一个示例来向您展示重载和重写是如何工作的。