您的位置:首页 > 编程语言 > Java开发

Java学习之方法重载和方法重写(覆盖)比较

2015-08-26 22:05 661 查看


方法重载和方法覆盖

请带着下面两点来看文章:

覆盖即重写,覆盖不等于重载,即重写不等于重载。
覆盖(重写)蕴含继承性,而重载只能在本类中使用,不含继承。

方法名和参数列表的比较


方法覆盖中的方法名和参数

首先创建基类Shape:

[code]publicclassShape{
publicvoiddraw(){
System.out.println("Shape.draw()");
}
}
[/code]

子类Circle:

[code]publicclassCircleextendsShape{
publicvoiddraw(){
System.out.println("Circle.draw()");
}
}
[/code]

>注意:子类没有在方法上添加`@Override`注解

此时修改父类Shape的draw方法名为draw1:

[code]/*publicvoiddraw(){
System.out.println("Shape.draw()");
}*/
publicvoiddraw1(){
System.out.println("Shape.draw()");
}
[/code]

编译器不会报错,因为子类的`draw()`并没有覆盖(重写)父类的`draw()`,现在在子类Circle的draw方法上添加注解`@Override`,此时子类Circle如下,下划线表示该方法报错(下面不再说明)

[code]/*publicvoiddraw(){
System.out.println("Circle.draw()");
}*/
@Override
publicvoiddraw(){
System.out.println("Circle.draw()");
}
[/code]

此时,编译器报错,提示:子类Cricle的draw方法必须重写或实现父类的draw1方法。

结论:重写父类方法时必须加`@Override`注解,且方法名要相同。



再修改父类的方法如下:

[code]/*publicvoiddraw(){
System.out.println("Shape.draw()");
}*/
/*publicvoiddraw1(){
System.out.println("Shape.draw()");
}*/
publicvoiddraw(inti){
}
[/code]

子类如下:

[code]...
/*@Override
publicvoiddraw(){
System.out.println("Circle.draw()");
}*/
@Override
publicvoiddraw(floati){
System.out.println("Circle.draw()");
}
[/code]

子类的覆盖方法报错,提示:必须实现父类的相关方法或移除`@Override`注解。

在修改子类draw方法如下:

[code]@Override
publicvoiddraw(inti,intj){
super.draw(i);
}
[/code]

子类的覆盖方法也报如上错误。

结论:重写或覆盖父类方法时,参数类型和参数列表个数必须相同。


方法重载中的方法名和参数

在Cricle类中添加以下方法:

[code]...
publicvoiderase(){
System.out.println("Circle.erase()");
}}[/code]

编译器报错,提示重复的erase()方法。

修改后如下:

[code]publicvoiderase(){
System.out.println("Circle.erase()");
}
publicvoiderase(inti){
System.out.println("Circle.erase()");
}
[/code]

编译通过。

伪论(下面给出证明):重载的方法名相同,但参数个数必须不同。

在修改Cricle类如下:

[code]...
publicvoiderase(inti,intj){
System.out.println("Circle.erase()");
}
publicvoiderase(inti,Strings){
System.out.println("Circle.erase()");
}
[/code]

编译通过。

结论:重载的方法名必须相同,参数个数可以不同,但参数类型必须不同。一句话就是,重载的方法名必须相同且参数列表必须不同。


返回值类型的比较


方法覆盖中的返回值类型

父类Shape:

[code]...
publicStringdraw(){
return"Shape.draw()";
}
[/code]

子类Circle:

[code]...
@Override
publicintdraw(){
returnsuper.draw();
}
[/code]

编译器不同通过。提示和父类的draw方法的返回值类型不兼容。

结论:方法覆盖的返回值类型必须和父类相兼容。


方法重载中的返回值类型

Cricle类:

[code]privateinterase(inti,intj){
return0;
}
privatevoiderase(inti,intj){
System.out.println("Circle.erase()");
}
[/code]

编译不通过,提示重复的erase(int,int)方法。

修改后:

[code]privateinterase(inti,intj){
return0;
}
privatevoiderase(inti,Stringj){
System.out.println("Circle.erase()");
}
[/code]

编译通过。

结论:方法重载的返回值类型可以不同,但前提是参数列表不同。


访问权限的比较

方法覆盖中的访问权限

还原父类Shape:

[code]publicclassShape{
publicvoiddraw(){
System.out.println("Shape.draw()");
}
}
[/code]

此时在子类Cricle中修改draw方法的访问权限:

[code]@Override
privatevoiddraw(){
System.out.println("Circle.draw()");
}
[/code]

编译器报错,提示:不能降低从父类Shape继承来的方法的可见性

此时无论修改子类Cricle中的draw方法的访问权限为protected、private还是默认级别都提示不能降低从父类继承来的方法的可见性。

只能将子类的draw方法的访问权限设置为public才可以编译通过

此时修改父类draw方法的访问权限为private:

[code]privatevoiddraw(){
System.out.println("Shape.draw()");
}
[/code]



子类:

[code]@Override
publicvoiddraw(){
System.out.println("Circle.draw()");
}
[/code]

编译器报错,提示:必须实现父类的draw方法。

此时修改父类draw方法的访问权限为protected或默认级别,编译器就不报错了。

结论:父类中被private修饰的方法无法被子类覆盖,即无法被子类继承。



方法重载中的访问权限

Circle类代码:

[code]publicvoiderase(){
System.out.println("Circle.erase()");
}
protectedvoiderase(inti){
System.out.println("Circle.erase()");
}
privatevoiderase(inti,intj){
System.out.println("Circle.erase()");
}
voiderase(inti,Strings){
System.out.println("Circle.erase()");
}
[/code]

编译通过。

结论:重载方法对访问权限不敏感。



OK,如果有错误或遗漏的地方请评论指出,互相交流,共同进步。谢谢!





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: