写在开头

请聊一聊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. 复杂查询so easy ,GaussDB(for Cassandra)推Lucene引擎全新解决方案

    摘要:复杂查询so easy!GaussDB(for Cassandra)新特性来袭. 本文分享自华为云社区<来了!GaussDB(for Cassandra)新特性亮相>,作者:Gaus ...

  2. 10年经验总结,华为fellow教你如何成为一名优秀的架构师?

    摘要:华为云首席架构师分享成为架构师必备的一些特质和能力. 本文分享自华为云社区<10年经验总结,华为fellow教你如何成为一名优秀的架构师?>,作者: 技术火炬手 . 在<云享人 ...

  3. Axure 辅助线--栅格化布局

    全局辅助线 在所有页面都会显示,比如主页面是框架.子页面通过[内联框架]去加载,为了子页面的元件不偏移,可以创建创建全局辅助线 页面辅助线

  4. PPT 没有电脑如何制作PPT

    没有电脑如何制作PPT

  5. Hugging Face: 代码生成模型的预训练和微调

    和大家分享我们的机器学习工程师 Loubna Ben Allal 在 10 月上海 KubeCon 大会的主题演讲 题目是: 代码生成模型的预训练和微调 演讲介绍了构建和训练大型代码模型比如: Sta ...

  6. PS CJ20N 项目定义属性字段增强

    一.CJ20N添加字段  二.用户出口  三.校验必输项 博客频遭盗窃,请移步公众号"斌将军",输入关键字"项目定义字段增强"查看 TRANSLATE with ...

  7. OS | 银行家算法C语言实现

    算法简介 银行家算法(Banker's Algorithm)是一个避免死锁( Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法.它以银行借贷 ...

  8. vue学习笔记 一、环境搭建

    系列导航 vue学习笔记 一.环境搭建 vue学习笔记 二.环境搭建+项目创建 vue学习笔记 三.文件和目录结构 vue学习笔记 四.定义组件(组件基本结构) vue学习笔记 五.创建子组件实例 v ...

  9. appium(二)安装(Android)

    一.安装Appium-desktop 1.官网下载安装包: http://appium.io/

  10. Advanced .Net Debugging 1:你必须知道的调试工具

    一.简介    我曾看到过许多开发人员使用错误的工具来分析问题,更有甚者,有些人连任何工具都没有使用.他们采取的分析方法通常包括:输出更多的调试信息,或者做一些临时性的代码审查.这里的临时性是指,通过 ...