码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-08-26 22:21:45      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:方法重载   方法覆盖   重写   override   

方法重载和方法覆盖


请带着下面两点来看文章:
  1. 覆盖即重写,覆盖不等于重载,即重写不等于重载
  2. 覆盖(重写)蕴含继承性,而重载只能在本类中使用,不含继承。

方法名和参数列表的比较


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


首先创建基类Shape:


public class Shape {
 
public void draw() {
System.out.println("Shape.draw()");
}
}

子类Circle:

public class Circle extends Shape {
 
public void draw() {
System.out.println("Circle.draw()");
}
}

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

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

/*public void draw() {
System.out.println("Shape.draw()");
}*/
public void draw1() {
System.out.println("Shape.draw()");
}

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

/*public void draw() {
System.out.println("Circle.draw()");
}*/
@Override
public void draw() {
System.out.println("Circle.draw()");
}

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

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

再修改父类的方法如下:

/*public void draw() {
System.out.println("Shape.draw()");
}*/
/*public void draw1() {
System.out.println("Shape.draw()");
}*/
public void draw(int i) {
}

子类如下:

...
/*@Override
public void draw() {
System.out.println("Circle.draw()");
}*/
@Override
public void draw(float i) {
System.out.println("Circle.draw()");
}

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

在修改子类draw方法如下:

@Override
public void draw(int i, int j) {
super.draw(i);
}

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


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

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

在Cricle类中添加以下方法:

...
public void erase() {
System.out.println("Circle.erase()");
}
}

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

修改后如下:

public void erase() {
System.out.println("Circle.erase()");
}
public void erase(int i) {
System.out.println("Circle.erase()");
}

编译通过。

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

在修改Cricle类如下:

...
public void erase(int i, int j) {
System.out.println("Circle.erase()");
}
public void erase(int i, String s) {
System.out.println("Circle.erase()");
}

编译通过。

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

返回值类型的比较


方法覆盖中的返回值类型


父类Shape:

... 
public String draw() {
return "Shape.draw()";
}

子类Circle:

...
@Override
public int draw() {
return super.draw();
}

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

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

方法重载中的返回值类型


Cricle类:

private int erase(int i, int j) {
return 0;
}
private void erase(int i, int j) {
System.out.println("Circle.erase()");
}

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

修改后:

private int erase(int i, int j) {
return 0;
}
private void erase(int i, String j) {
System.out.println("Circle.erase()");
}

编译通过。

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

访问权限的比较


方法覆盖中的访问权限


还原父类Shape:

public class Shape {
 
public void draw() {
System.out.println("Shape.draw()");
}
}

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

@Override
private void draw() {
System.out.println("Circle.draw()");
}

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

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

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


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

private void draw() {
System.out.println("Shape.draw()");
}
 
子类:

@Override
public void draw() {
System.out.println("Circle.draw()");
}

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

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

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

方法重载中的访问权限


Circle类代码:

public void erase() {
System.out.println("Circle.erase()");
}
protected void erase(int i) {
System.out.println("Circle.erase()");
}
private void erase(int i, int j) {
System.out.println("Circle.erase()");
}
void erase(int i, String s) {
System.out.println("Circle.erase()");
}

编译通过。

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

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















版权声明:欢迎转载!请注明出处:http://blog.csdn.net/u011726984

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

标签:方法重载   方法覆盖   重写   override   

原文地址:http://blog.csdn.net/u011726984/article/details/48011767

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!