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

方法重载和方法覆盖


请带着下面两点来看文章:
  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, 如果有错误或遗漏的地方请评论指出,互相交流,共同进步。谢谢!















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值