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,如果有错误或遗漏的地方请评论指出,互相交流,共同进步。谢谢!
相关文章推荐
- Struts2属性驱动与模型驱动
- 大龄屌丝自学笔记--Java零基础到菜鸟--012
- java ConcurrentHashMap
- Java多线程 -- 线程池
- Spring MVC工作原理
- 在Eclipse的workplace外的工程使用兼容性actionbar提示No resource found that matches the given name的解决方法
- Easyui+Spring+Mybatis完整示例(后台)
- java mysql 数据类型对照
- Ioc的基本概念《Spring揭秘》第2章笔记
- 每日五题(java基础)
- MyEclipse下实现git克隆代码到本地
- 最全的Spring面试题和答案
- Java之Comparable接口和Comparator接口
- 【JavaSE】day04_Collection_Iterator_新循环_泛型
- Sqlite_操作数据库_JDBC连接Java与数据库
- Java多线程 -- volatile关键字
- Java高手需要注意的25个学习目标
- Highcharts+Spring饼图使用实例
- Java多线程 -- 死锁
- eclipse 查找jar包内的class文件 快捷键