一. 方法重载

方法重载:当同一个类中有两个或两个以上相同命名的方法。

当方法重载时,必须要保证每两个方法之前的方法签名(Signature)是不同的。这意味着这两个方法有着不同数量的参数或者参数的类型不同,也可都不同。

方法签名:方法签名包括一个方法的名字以及参数列表。

我们来看下面这一段代码:

   //return the max of two int valuespublic static int max(int num1, int num2) {System.out.println("Method1 invoked.");if (num1 > num2)return num1;elsereturn num2;}//return the max of two double valuespublic static double max(double num1, double num2) {System.out.println("Method2 invoked.");if (num1 > num2)return num1;elsereturn num2;}// return the max of three double valuespublic static double max(int num1, int num2, double num3) {System.out.println("Method3 invoked.");return max(max(num1, num2), num3);}

第一个方法的方法签名就是 max(int, int),同理第二个方法的签名就是 max(double, double) 。

在这一段代码中的三个方法就在同一个类中,相同的命名,不同的方法签名,那么这就是所谓的方法重载了。那我们为什么要运用到方法重载呢?因为在不同情境中我们需要运用不同类型的参数,虽然这可以用泛类实现,但是有时候还需要不同数量的参数。最常见的方法重载的运用就是构造函数(Constructor)。

方法一求的是最大整数,方法二求的是最大双精度数,方法三是求三个双精度数中的最大值,这三个方法都有相同的命名max。

    public static void main(String[] args) {System.out.println(max(3, 4));System.out.println(max(3.0, 5.5));System.out.println(max(3, 5, 10.88));}

当我们运行这个程序的时候,结果如下:

Method1 invoked.
4
Method2 invoked.
5.5
Method3 invoked.
Method1 invoked.
Method2 invoked.
10.88

前两个方法都一目了然,但第三个方法为什么分别调用了方法1和方法2呢。因为调用方法3时,传入的参数列表中前两个参数为int整数型。Java编译器搜寻方法max中最精确匹配的方法,因为方法1max(int, int) 比方法2max(double, double) 更精确,所以方法1被调用。之后返回数字5与10.88调用方法,此时我们发现没有一个方法是和此时的参数类型(int, double)完全相符的,但是为什么方法2成功被调用了呢。

这是因为Java的自动转换类型机制(Automatic Type Conversion),当Java找不到一个完全相符的方法时,会自动尝试类型转换。根据下图可以转换的方向,所以方法2被调用。

这种自动转换看起来很方便,但有时候也会引起问题。

歧义调用:当调用一个方法,有两个或两个以上的匹配时,Java编译器无法判断哪个是最精确的匹配。歧义调用会产生一个编译错误。

我们来看这样一段代码:

 public static double max(int num1, double num2) {if (num1 > num2)return num1;elsereturn num2;}public static double max(double num1, int num2) {if (num1 > num2)return num1;elsereturn num2;}

当我们尝试调用方法,比如说max(int, int), Java就无法判断哪一个方法更精确,从而导致了一个错误。通常IDE会提示错误并提示修改。

在方法重载的时候还需要注意:

  1. 返回类型不可以重载。方法签名并不包括返回类型,所以改变返回类型并不是方法重载。且Java不允许在同一个类中有两个相同方法签名不同返回类型的方法。

    这是错误的:

    public class Sample {public int computeSth(int n) {..}public double computeSth(int n) {..}
    }
    
  2. 运算符号不可以重载。虽然其他语音,像C++允许你重载符号(+, -, etc.), Java并不允许。

二. 方法重写

方法重写: 在子类中重新定义从父类中继承到的方法。

在子类中重写的方法需要使用和父类一样的方法签名以及返回类型。

通常来说重写的方法是不能改变返回类型的,而且也不能改变他是void还是可以返回值的。但是,在Java 5.0之后的版本中,如果返回的类型是一个类A,那么在重写的方法中返回的类型可以是所有继承了A类的子类的类型,这被称为协变返回类型(Covariant Return Type)。

这是被允许的:

public class BaseClass {...public Employee getS(int money)...}public class DerivedClass extends BaseClass {...public partTimeEmployee getS(int money)...}

在重写方法的时候还需要注意的是访问权限的问题。在子类中重写的方法只能将他从低权限改变到高权限(private --> public)而并不能将他从高权限改变到低权限(publc --> private)。

如果不想父类中的方法被重写,那我可以在方法的前面加上final修饰符,这样该方法就不能在子类中被重新定义。如果在定义类的时候加上final修饰符,那么这个类将不能被继承。

请注意,静态方法(static)可以被继承,但不能被重写。如果在子类中静态方法被重新定义的话,那么父类中的该静态方法将会被隐藏,但仍可通过类名.方法名(SuperClassName.staticMethodName)的方式被调用。

三. 区别

方法重载时使用同样的名字不同的签名定义多个方法;重写是在子类中对一个方法进行新的实现(相同签名以及相同返回类型)。

请思考以下两段代码的输出是什么。
重写的例子:

public class TestOverriding {public static void main(String[] args) {A a = new A();a.p(10);a.p(10.0);}
}class B {public void p(double i) {System.out.println(i * 2);}
}class A extends B {// overrides the method in B@Overridepublic void p(double i) {System.out.println(i);}
}

重载的例子:

public class TestOverloading {public static void main(String[] args) {C c = new C();c.p(10);c.p(10.0);}
}class D {public void p(double i) {System.out.println(i * 2);}
}class C extends D {// overloads the method in Dpublic void p(int i) {System.out.println(i);}
}

第一段段代码中main函数里的两行均调用了类A中的方法p(double i),所以输出为 10.0 和 10.0. 因为类A中的方法p重写了父类B中的方法p。
第二段段代码中main函数里的 c.p(10) 调用了类C中的方法p,c.p(10.0)调用了类D中的方法p。所以输出结果为 10 和 20.0。
如果做错的话就再回头看看方法重写和重载的定义。

还需注意的是,方法重写一定发生在继承相关的不同类中,但是方法重载可以发生在同一个类中也可以发生在继承关系的不同类中。在通用的IDE中都可以加入@override重写标记去提醒IDE和自己该方法被重写了。

JAVA中的方法重载(Overloading)和方法重写(Overriding)相关推荐

  1. java 方法重载调用_Java方法的定义以及调用、方法重载、可变参数以及递归

    何谓方法 Java方法是语句的集合,它们在一起执行一个功能 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 System.out.println();/ ...

  2. java语言 文件上传,java中实现文件上传的方法

    java中实现文件上传的方法 发布时间:2020-06-19 10:29:11 来源:亿速云 阅读:86 作者:Leah 这篇文章给大家分享的是java中实现文件上传的方法,相信大部分人都还没学会这个 ...

  3. Java中创建数组的几种方法

    Java中创建数组的几种方法 public static void main(String[] args) { //创建数组的第一种方法 int[] arr=new int[6]; int intVa ...

  4. 在 Java 中初始化 List 的五种方法

    转载自  在 Java 中初始化 List 的五种方法 Java 中经常需要使用到 List,下面简单介绍几种常见的初始化方式. 1.构造 List 后使用 List.add 初始化 List< ...

  5. 高级 | Java中获取类名的3种方法

    转载自 高级 | Java中获取类名的3种方法 获取类名的方法 Java 中获取类名的方式主要有以下三种. getName() 返回的是虚拟机里面的class的类名表现形式. getCanonical ...

  6. 谈谈java中遍历Map的几种方法

    java中的map遍历有多种方法,从最早的Iterator,到java5支持的foreach,再到java8 Lambda,让我们一起来看下具体的用法以及各自的优缺点 先初始化一个map public ...

  7. Java 中 List 分片的 5 种方法!

    作者 | 王磊 来源 | Java中文社群(ID:javacn666) 转载请联系授权(微信ID:GG_Stone) 前些天在实现 MyBatis 批量插入时遇到了一个问题,当批量插入的数据量比较大时 ...

  8. Java中的length字段和length()方法

    本文主要讲述Java中的length字段和length()方法,有需要的朋友可以参考下,更多Java教程知识,请登陆疯狂软件教育官网. 首先,你能快速回答下面的问题吗? 如果没有IDE(集成开发环境) ...

  9. [转载] java中对象作为参数传递给一个方法,到底是值传递,还是引用传递

    参考链接: 用Java传递和返回对象 看完绝对清晰~ java中对象作为参数传递给一个方法,到底是值传递,还是引用传递? pdd:所谓java只有按值传递:基本类型  值传递:引用类型,地址值传递,所 ...

  10. Java中String字符串截取几种方法(substring,split)

    Java中String字符串截取几种方法 substring,split 这是一个Java中的String的基础用法的演示. 下面通过代码对大家进行讲解 substring 这里用来ndexOf,la ...

最新文章

  1. 基础二(格式化字符串、运算符和编码)
  2. C语言循环队列的实现方法,C语言循环队列(数组实现)
  3. java电话计费系统_java 连接数据库开发的电话计费管理系统
  4. SQLserver删除某数据库中所有表 方法 二
  5. JaveScript运算符(JS知识点归纳三)
  6. php计算1992年到现在,1992年以前 | 物质计算科学研究室 - Powered by MYPHP
  7. Python中操作myslq的方法
  8. VS2008 安装失败(“Web 创作组件”无法)
  9. 数字头盔摄像头是一个智能选项
  10. 43. 算法调用优先于手写的循环
  11. ES(Elasticsearch)解除索引只读限制
  12. Java、素数的个数
  13. 网络连接状态断开服务器无响应,解决SSH自动断线,无响应的问题。
  14. ENSP-----ISIS协议
  15. 使用C#或C++语言实现微信自动加好友的功能(附接口SDK及源码)
  16. 达内CEO受邀出席搜狐“2011职业教育高峰论坛”
  17. 互联网时代下的市场营销
  18. 学术期刊数据库---EBSCO
  19. MATLAB | 艺术就是画圈圈
  20. Java获取Excel中链接的文件

热门文章

  1. Android官方文档翻译 十二 3.Supporting Different Devices
  2. python3GUI--天气预报小工具By:PyQt5(附源码)
  3. 算法唯手熟尔(PAT剩余清单 or leetcode)---希望可以日更
  4. P2754 [CTSC1999] 家园
  5. MATLAB之时频域乐器信号的分析与处理
  6. Jsoncpp如何使用及样例
  7. 财务建模完整指南第五讲——第五届CVA估值建模
  8. 网络基本概念备忘:MAC地址,端口,HTTP状态码
  9. 338 比特位计数(动态规划-递推)
  10. 为了这个羞羞的项目,我差点成为“鉴黄师”