Java基础之多态的实现重载 vs 重写

该项目源码地址:https://github.com/lastwhispers/code/tree/master/java-basic

前言

重载(overload)和重写(override)这两个概念有时候经常会搞混,这里记录一下。

在写这个笔记之前一直很纠结“重载”到底属不属于多态?
有人说属于、有人说不属于。https://bbs.csdn.net/topics/300257765
这个帖子讨论的很激烈。我觉得这个36楼的大哥说的有理,这些都是些“名词之争”。

多态是指只有到运行时才能确定要执行的代码,即指的是后期绑定,这样Overload就不属于多态。
在C++语言中,如果不将Override方法声明为Virtual的,也应该不属于多态。
不过话又说回来,很多书上说overload是方法意义上的多态,都是些名词之争
关键是自己要理解各自的意义,会用万岁!!

在stackoverflow也有类似观点
https://stackoverflow.com/questions/2400284/is-method-overloading-considered-polymorphism

"Polymorphism" is just a word and doesn't have a globally agreed-upon, precise definition. You will not be enlightened by either a "yes" or a "no" answer to your question because the difference will be in the chosen definition of "polymorphism" and not in the essence of method overloading as a feature of any particular language. You can see the evidence of that in most of the other answers here, each introducing its own definition and then evaluating the language feature against it.
“多态性”只是一个词,并没有全球一致的精确定义。 你不会被你的问题的“是”或“否”答案所启发,因为差异将在所选择的“多态性”定义中,而不是作为任何特定语言的特征的方法重载的本质。 你可以在这里看到大多数其他答案中的证据,每个答案都引入了自己的定义,然后根据它来评估语言特征。

也就是说“多态性”并没有一个像数学公式一样的很严格的定义,可能在不同的面向对象编程语言中定义不一样,然后实现也不一样。

所以,本文以"重载是编译时的多态实现,重写是运行时的多态实现"的观点进行撰述。

1. 方法重载

什么是方法重载?
方法的重载是指在一个类中,出现多个方法名相同,但参数个数或参数类型不同的方法,则称为方法的重载。Java在执行具有重载关系的方法时,将根据调用参数的个数和类型区分具体执行的是哪个方法。

方法重载规则:方法名称必须相同,参数个数、次序、类型任意一项不同;
无关条件:访问修饰符、返回值、抛异常;

重载规则实例

public void overloadFun() {
         // 无参函数
}

加上参数,对overloadFun()方法进行重载

public void overloadFun(Long id) {
        // 重载overloadFun,参数个数不同
}

更换参数类型,对overloadFun()方法进行重载

public void overloadFun(Integer id) {
        // 重载overloadFun,参数类型不同
}

增加参数个数,对overloadFun()方法进行重载

public void overloadFun(Long id, String name) {
      // 重载overloadFun,参数个数不同
}

更换参数次序,对overloadFun()方法进行重载

public void overloadFun(String name, Long id) {
        // 重载overloadFun,参数顺序不同
}

无关条件实例

// 抛出异常不同,并不能构成函数重载
public void overloadFun() throws Exception{
}
// 访问修饰符不同,并不能构成函数重载
private void overloadFun(Integer id) {
}
// 返回值不同,并不能构成函数重载
public int overloadFun(){
    return 0;
}

2. 方法重写

什么是方法重写?
当子类继承父类中所有可能被子类访问的成员方法时,如果子类的方法名与父类的方法名相同,那么子类就不能继承父类的方法,此时,称子类的方法重写了父类的方法。重写体现了子类补充或者改变父类方法的能力,通过重写,可以使一个方法在不同的子类中表现出不同的行为。

方法重写规则:

  • 子类与父类的方法名、参数列表、返回值类型必须保持一致;
  • 重写方法的访问修饰符权限范围必须大于等于父类方法;
  • 重写方法抛出的异常范围不能大于父类方法;

实例

先编写一个父类,注意该方法时使用protected修饰,并且抛出ArithmeticException。

public class SuperClass {
    protected int overrideFun(int a, int b) throws ArithmeticException {
        int divisor = a / b;
        return divisor;
    }
}

再编写一个子类继承SuperClass并重写overrideFun方法。

public class SubClass extends SuperClass {

    @Override
    protected int overrideFun(int a, int b) {
        if (b == 0) {
            return Integer.MAX_VALUE;//说明除数为0
        }
        return a / b;
    }
}

通常子类重写父类方法是因为父类的方法满足不了子类的需求,子类对父类的方法进行重写。所以让父类除法时没有做除数非0的判断,让子类重写父类的方法,进行除数非0的判断。

我们再来试试重写对访问修饰符和异常的要求。

重写方法的访问修饰符权限范围必须大于等于父类方法。(访问修饰符权限public>protected>private)

我们将子类重写的overrideFun方法访问修饰符改为“private”。

重写方法的访问修饰符权限范围必须大于等于父类方法

此时就会报错,因为父类的引用指向子类对象,调用子类对象方法会访问不到,违背了多态性。

重写方法抛出的异常范围不能大于父类方法

父类的overrideFun方法抛出了ArithmeticException,我们在子类的overrideFun方法抛出范围更大Exception。

重写方法抛出的异常范围不能大于父类方法

此时就会报错,因为重写方法抛出的异常范围大于父类方法。

3. 总结

多态:

  • 方法重载(overload)实现的是编译时的多态性(前期绑定)。
  • 方法重写(override)实现的是运行时的多态性(后期绑定)。运行时的多态是面向对象的精髓。
  • 实现多态:1. 方法重写(子类继承父类并重写父类中已有的或者抽象方法)2. 对象造型(用父类型引用指向子类型对象,这样同样的引用调用同样的方法就会根据指向的对象不同表现出不同的行为)

重载(overload):

  • 发生在同一个类中的多个同名方法中。
  • 参数的数据类型或者参数的个数、顺序不同。
  • 访问修饰符、返回值、抛异常不会影响重载。
  • 目的:节省类中的命名资源,提高代码的可读性。

重写(override):

  • 发生在有继承关系的父类和子类中。
  • 重写方法的声明部分要和父类保持一致,访问权限不能小于父类,抛出异常的范围不能大于父类。
  • 一般是父类的该方法满足不了子类的需求,子类对父类的方法进行重写。

参考

https://blog.csdn.net/lijing742180/article/details/90049341

https://bbs.csdn.net/topics/300257765

https://stackoverflow.com/questions/2400284/is-method-overloading-considered-polymorphism

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270