方法重载和方法覆盖
请带着下面两点来看文章:
- 覆盖即重写,覆盖不等于重载,即重写不等于重载。
- 覆盖(重写)蕴含继承性,而重载只能在本类中使用,不含继承。
方法名和参数列表的比较
方法覆盖中的方法名和参数
首先创建基类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