写在开头

请聊一聊Java中方法的重写和重载?

这个问题应该是各大厂面试时问的最多的话题之一了,它们几乎贯穿了我们日常的开发工作,在过往的博客中我们多多少少都提到过重载重写,而今天我们就一起来详细的学习一下这二者的功能与区别!

重载与重写的定义

重写: 类实现接口或者子类继承父类时,保持方法签名相同,用不同的方法体来实现不同的功能,这也是Java三大特性之一多态的具体实现,是垂直方向的“类间行为”。

重载: 在同一个类或者父类与子类之间,保持方法名称相同,参数类型,参数数量,参数顺序不同的一种实现,是水平方向上的“类内行为”,同一个类中,或者父子类中。

方法的重写

如下代码中是一个最简单的重写的实现

public class Dog extends Animal{
public static void main(String[] args) {
Dog dog = new Dog();
dog.method1();
}
@Override
public void method1() {
System.out.println("狗子爱奔跑");
}
}
class Animal {
public void method1(){
System.out.println("我是动物!");
};
}

重写的规则

1、重写发生在子类继承父类
2、参数列表必须完全与被重写方法的相同
3、重写父类方法时,修改方法的权限只能从小范围到大范围
4、返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的子类(JDK1.5 及更早版本返回类型要一样,JDK1.7 及更高版本可以不同)
5、访问权限不能比父类中被重写的方法的访问权限更低。如:父类的方法被声明为 public,那么子类中重写该方法不能声明为 protected
6、重写方法不能抛出新的检查异常和比被重写方法申明更宽泛的异常(即只能抛出父类方法抛出异常的子类)
7、声明为 final 的方法不能被重写
8、声明为 static 的方法不能被重写
9、声明为 private 的方法不能被重写

【补充说明】

上面的9条规则中,前面6条应该没什么太多的疑问,访问权限、异常声明范围,子类小于父类,就如同包含与被包含关系,狗子(子类)是动物(父类),那它所拥有的一切自然都要在动物的范畴内!

第7条,final关键字修饰的方法,一旦初始化引用不可变,具体可参考之前发的这篇文章

面试官:小伙子来说一说Java中final关键字

第8点,static修饰的方法不能被重写,这也是一个考点,很好理解,static修饰的方法属于类方法,在调用的时候直接通过类名.方法名即可,而重写也就是多态是基于对象的,一个静态的方法不会联系到任何实例上,所以也就不存在重写了!但是很多面试官为了考验应聘着的细心,会紧接着问一句,那子类中可以有一个和父类方法签名一致的静态方法吗?

答案是肯定的,如果父类中含有一个静态方法,且在子类中也含有一个返回类型、方法名、参数列表均与之相同的静态方法,那么该子类实际上只是

将父类中的该同名方法进行了隐藏,而非重写。 换句话说,父类和子类中含有的其实是两个没有关系的方法,它们的行为也并不具有多态性。

static关键字内容,可以看这篇文章:深入理解Java中的static关键字

第9条就更没什么好说的了,private表示方法是本类私有,其他类均不可见,更不可能重写了。

方法的重载

重载是发生在编译期间的一种静态绑定,编译器通过方法签名来定位具体重载的哪个方法,如String的valueOf就是一个方法重载的案例典范,上代码!

目前String中valueOf重载的方法已多达十几种,用以实现不同的数据类型转换为字符串的逻辑。

是不是觉得重载很简单?不就是方法名相同的情况下,传入不同参数即可调用不同的重载方法,那么我们看看下面的代码



这时若我们分别调用1、method(),2、method(1),3、method(1L),4、method(null),猜一下答案,嘿嘿



调用1时方法1和方法5均可满足条件(可变参数,参数个数为0或多个),但因为JVM重载方法时优先通过精准匹配进行选择,所以这里会选择方法1;调用2时,方法2、3、4、5均满足,同样因为精准匹配的原因,选择了方法2;调用3时,因为重载方法中没有参数为long类型的,所以会通过子类向上转型继承路线依次匹配,最终调用到了方法4;这里4的调用被注释掉了,原因是报错啦,出现了模糊匹配。



参数null可以匹配任何一个类对象,这里从满足从子类向上转型进行匹配,但在Integer和可变参数的选择上,编译器无法选择,所以编译报错。

由上述的例子其实我们不难看出,在多个重载方法均满足条件时,编译器对于重载的选择是有优先顺序的,下面进行了整理。

编译器选择顺序(从高到底)
精准匹配
基本数据类型,自动转换为更大范围的基本类型
通过装箱与拆箱进行匹配
通过子类向上转型继承路线依次匹配
通过可变参数匹配

重载的规则

1、被重载的方法参数列表(个数或类型)不一样
2、被重载的方法可以修改返回类型
3、被重载的方法可以修改访问修饰符
4、被重载的方法可以修改异常抛出
5、方法能够在同一个类中或者在一个子类中被重载
6、无法以返回值类型作为重载函数的区分标准

【补充说明】

以上6点规则中,前5点比较好理解,第6点也是很多面试官经常会追问的问题,为什么重载的方法,不能将返回值类型作为参考标准。

首先,我们看一下这段代码:

public class Dog {
public int method1(int a,int b) {
return a+b;
}
public short method1(int a,int b) {
return (short)(a+b);
}
}

这段代码中的两个方法,就是保持了返回值类型不同,但提示方法已经被定义,无法重载,说明仅靠返回值类型无法作为方法重载的参考标准!,仔细想想也很容易明白,并不是所有的方法都是有返回值的,难道无返回值的方法重载时,我们还要依赖返回值去判断?

​写到这里,俺又想到了一个问题,你们觉得main()方法可以重载吗

public class OverloadingMain {
public static void main(String[] args) {
System.out.println("String[] args");
} public static void main(String args) {
System.out.println("String args");
} public static void main() {
System.out.println("无参");
}
}

输出:

String[] args

显然,重载是被允许的,但JVM在运行时,只会将那个参数为String[] args的静态main方法作为程序的入口,其他方法只能通过调用去实现打印结果!

重载与重写的区别

基于以上的分析,我们可以精炼出重载与重写的重要区别:

作用范围: 重写的作用范围是父类和子类之间;重载是发生在一个类里面

参数列表: 重载必须不同;重写不能修改

返回类型: 重载可修改;重写方法返回相同类型或子类

抛出异常: 重载可修改;重写可减少或删除,一定不能抛出新的或者更广的异常

访问权限: 重载可修改;重写一定不能做更严格的限制

每日一道Java面试题:方法重载与方法重写,这把指定让你明明白白!的更多相关文章

  1. Java笔记 —— 方法重载和方法重写

    Java笔记 -- 方法重载和方法重写 h2{ color: #4ABCDE; } a{ text-decoration: none !important; } a:hover{ color: red ...

  2. JAVA学习(七):方法重载与方法重写、thiskeyword和superkeyword

    方法重载与方法重写.thiskeyword和superkeyword 1.方法重载 重载可以使具有同样名称但不同数目和类型參数的类传递给方法. 注: 一是重载方法的參数列表必须与被重载的方法不同,而且 ...

  3. Java连载30-方法重载、方法递归

    一.方法重载 1.又被称为overload 2.方法重载使用场景 功能类似的时候,尽可能仍方法名相同(但是功能不同或者不相似的时候,方法名尽量不同) 3.什么条件满足之后,可以构成方法重载 (1)在同 ...

  4. Java学习总结之方法重载和方法重写

    在学习方法的阶段我学习了方法重载(Overload),而在学习面向对象三大特性之继承的时候我又学习了方法重写(Override).   概念: 方法重载:在同一个类中,允许存在一个以上的同名方法,只要 ...

  5. Java 方法重载与方法重写

    方法重载(Overload): 1.在同一个类中 2.方法名相同 3.参数的个数或类型不同 4.与方法的返回类型无关 5.与方法的修饰符无关 方法重写(Override): 方法重写必须是子类继承父类 ...

  6. AJPFX总结方法重载与方法重写的区别

    方法重载在同一个类中,可以出现同名方法,但是这些同名方法的参数列表必须不同,这样定义方法叫做方法重载.方法重载的特点重载的注意事项重载与返回值无关重载与具体的变量标识符无关重载只与方法名与参数相关重载 ...

  7. PHP面向对象编程——深入理解方法重载与方法覆盖(多态)

    什么是多态? 多态(Polymorphism)按字面的意思就是“多种状态”.在面向对象语言中,接口的多种不同的实现方式即为多态.引用Charlie Calverts对多态的描述——多态性是允许你将父对 ...

  8. PHP面向对象编程之深入理解方法重载与方法覆盖(多态)

    这篇文章主要介绍了PHP面向对象编程之深入理解方法重载与方法覆盖(多态)的相关资料,需要的朋友可以参考下: 什么是多态? 多态(Polymorphism)按字面的意思就是"多种状态" ...

  9. 疯狂java学习笔记之面向对象(六) - 构造器重载、方法重载和方法重写

    一.方法重载(Overload): Java允许同一个类中定义多个同名方法,只要形参不一样就可以,如果同一个类中包含了两个或两个以上方法名相同的方法,但形参列表不同,则被成为方法重载(两同一异). 同 ...

  10. Java 方法重载,方法重写(覆盖),继承等细节注意

    1.方法重载(method overload)的具体规范 如果有两个方法的方法名相同,但参数不一致,那么可以说一个方法是另一个方法的重载. 一.方法名一定要相同. 二.方法的参数表必须不同,包括参数的 ...

随机推荐

  1. 海量监控数据处理如何做,看华为云SRE案例分享

    摘要:openGemini的设计和优化都是根据时序数据特点而来,在面对海量运维监控数据处理需求时,openGemini显然更加有针对性. IT运维诞生于最早的信息化时代.在信息化时代,企业的信息化系统 ...

  2. 专注提升用户体验,Superset 1.3发布!

    近期Superset发布了新的版本1.3.0,此版本专注于提升用户体验.并进行了大量的改进与错误修复. 用户体验 此版本的一个主要目标是改进仪表盘原生过滤器.这些过滤器的级别为仪表盘级别,而不是图表级 ...

  3. 利用 Solon-web 框架写一个 Hello World

    Solon 项目的开源地址: https://gitee.com/noear/solon 最近看了不少别人写的各种框架的 Hello world 示例,有些看起来,真的很复杂. 今天,我们用号称简单到 ...

  4. API 设计最佳实践(简版)

    Restful API 本文简称API,是一个种面向资源的架构.在Restful中一个API对应一个资源,资源可以是文本,图片,视频等.API特征有如下: 每一个URI代表一种资源 客户端和服务器之间 ...

  5. 火爆全网的条形竞赛图,Python轻松实现

    这个动图叫条形竞赛图,非常适合制作随时间变动的数据. 我已经用streamlit+bar_chart_race实现了,然后白嫖了heroku的服务器,大家通过下面的网址上传csv格式的表格就可以轻松制 ...

  6. Leaflet 使用图片作为地图

    Leaflet 使用图片作为地图 关键代码: L.CRS.Simple.transformation = new L.Transformation(1, 0, 1, 0); // 坐标原点切换为左上角 ...

  7. 微信公众号短链实时阅读量、点赞数爬虫(不会Hook可用)

    众所周知,微信分享的公众号分享出的一般都是短链,在这个锻炼下使用浏览器打开并不能获取微信公众的阅读量点赞数等这些信息,如图1所示. 但是实际拥有详细信息的则是这个链接下面,提取链接所需要提交的信息包括 ...

  8. AtCoder Beginner Contest 217 D~E

    比赛链接:Here ABC水题, D - Cutting Woods 题意:开始一根木棒长度为 \(n\) 并以 \(1\) 为单位在木棒上标记\((1\sim n)\) ,输出 \(q\) 次操作 ...

  9. 题解 [HDU 6745] Dec (简单DP)

    来源:2020 年百度之星·程序设计大赛 - 初赛一 错误想法带来错的代码, 为什么一个简单DP题能被我想成复杂的贪心啊?? 初始有 \(a,b\) 两个正整数,每次可以从中选一个大于 1 的数减 1 ...

  10. L1-048 矩阵A乘以B (15分)

    给定两个矩阵A和B,要求你计算它们的乘积矩阵 \(AB\).需要注意的是,只有规模匹配的矩阵才可以相乘.即若A有 \(R_a\) 行.\(C_a\) 列,B有 \(R_b\) 行.\(C_b\) 列, ...