讨论/题目交流/Java 子类、父类有同名方法,返回类型不同,应该报错却为何运行成功?/
Java 子类、父类有同名方法,返回类型不同,应该报错却为何运行成功?
class Super
{
	public int get(){return 666;}   // 父类返回值666
}
class Demo15 extends Super
{
	public long get(){return 444;}	//子类继承,同名方法,类型不同,返回值444	
}
	
public class Test4_15 {

	public static void main(String[] args) 
	{
		Super s=new Demo15();
		System.out.println(s.get());

	}

}

我这里的结果是
666

我就很奇怪为什么没有报错呢?

我用的是Eclipse

展开讨论

因为这属于方法的 重写(overriding)

  1. 父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。

  2. 若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。

由上可知,你的实例中子类 Demo15 实际上重写了父类 Super 的方法 get(),因而可以正常运行,但返回的是父类方法的返回值。

这是为什么呢?因为虽然你写的两个 get() 在实质上是重写的关系,但是重写一般默认返回类型也需要相同,而你在父类和子类方法中返回类型分别是 int 和 long,在编译器里会显示如下:

360截图20190813204001933.jpg

可以看到,编译器把这种写法当作一个error看待,它给出的建议为:The return type is incompatible with Super.get(),overrides Super.get(),意思就是它识别出这是重写,但返回类型不匹配。

不过可以运行并且会返回666,如你之前提到的一样。

而把两个方法的返回类型统一后呢?我们来修改一下:
360截图20190813204430981.jpg

可以看到,现在编译器不再报错,且运行结果为子类方法返回结果 444:

360截图20190813204601638.jpg
这就证明此时子类重写成功,即完成在主程序中的 “向上转型”。

3
展开全部 7 讨论