Java 重写(Override)与重载(Overload)
重写(Override)
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。
在面向对象原则里,重写意味着可以重写任何现有方法。实例如下:
TestDog.java 文件代码:
以上实例编译运行结果如下:
动物可以移动 狗可以跑和走
在上面的例子中可以看到,尽管 b 属于 Animal 类型,但是它运行的是 Dog 类的 move方法。
这是由于在编译阶段,只是检查参数的引用类型。
然而在运行时,Java 虚拟机(JVM)指定对象的类型并且运行该对象的方法。
因此在上面的例子中,之所以能编译成功,是因为 Animal 类中存在 move 方法,然而运行时,运行的是特定对象的方法。
思考以下例子:
TestDog.java 文件代码:
以上实例编译运行结果如下:
TestDog.java:30: cannot find symbol symbol : method bark() location: class Animal b.bark(); ^
该程序将抛出一个编译错误,因为b的引用类型Animal没有bark方法。
方法的重写规则
参数列表必须完全与被重写方法的相同。
返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
父类的成员方法只能被它的子类重写。
声明为 final 的方法不能被重写。
声明为 static 的方法不能被重写,但是能够被再次声明。
子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
构造方法不能被重写。
如果不能继承一个方法,则不能重写这个方法。
Super 关键字的使用
当需要在子类中调用父类的被重写方法时,要使用 super 关键字。
TestDog.java 文件代码:
以上实例编译运行结果如下:
动物可以移动 狗可以跑和走
重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
重载规则:
- 被重载的方法必须改变参数列表(参数个数或类型不一样);
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
- 无法以返回值类型作为重载函数的区分标准。
实例
Overloading.java 文件代码:
重写与重载之间的区别
区别点 | 重载方法 | 重写方法 |
---|---|---|
参数列表 | 必须修改 | 一定不能修改 |
返回类型 | 可以修改 | 一定不能修改 |
异常 | 可以修改 | 可以减少或删除,一定不能抛出新的或者更广的异常 |
访问 | 可以修改 | 一定不能做更严格的限制(可以降低限制) |
总结
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
- (1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
- (2)方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
- (3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
horse
guo***gren1107@163.com
重载就是同样的一个方法能够根据输入数据的不同,做出不同的处理
重写就是当子类继承自父类的相同方法,输入数据一样,但要做出有别于父类的响应时,你就要覆盖父类方法
horse
guo***gren1107@163.com
我一点都不方
274***2310@qq.com
重载是同样的一个方法写多次变量修饰符不一样,当调用方法时,会自动判断给入数的类型,选取其中符合的方法。
输出结果:
我一点都不方
274***2310@qq.com
九刃
528***187@qq.com
补充:父类申明变量指向子类实例,该父类变量不能调用父类不存在的变量和方法,否则会编译错误
九刃
528***187@qq.com
luzhe610
sci***n@qq.com
重载与重写的简明理解:
luzhe610
sci***n@qq.com
TJ
133***99286@163.com
关于重载函数参数列表变化的可能性:
TJ
133***99286@163.com
Xander663
xan***1998@163.com
自定义的类重载比较函数的方法:
Xander663
xan***1998@163.com
Anchorin
Anc***in@foxmail.com
父类变量指向子类实例时可以使用强制类型转换访问父类没有的子类成员。
实例输出结果为:
Anchorin
Anc***in@foxmail.com
独孤尚良
yut***hanlin@qq.com
重写和重载的区别,以红烧为例。
红烧是一种做菜方法,可用来被比作 java 的方法。食材可以被比作为参数。厨师师徒可被比作为父子类。
方法的继承可以看做红烧这个做菜方法厨师老师传给厨师徒弟。
同样的红烧鱼,厨师老师的红烧方法传给厨师徒弟后,厨师徒弟在红烧方法上做了改动,这是红烧方法的重写,就相当于 java 的方法重写。
重写代码类似如下:
我找厨师徒弟做菜,我说要红烧,我给他鱼他就做的是红烧鱼,我给他排骨他就做的是红烧排骨,我给他鱼和排骨他就做的是红烧鱼和排骨。食材的不同就相当于 java 方法的参数不同,这个是重载。
重载代码类似如下:
独孤尚良
yut***hanlin@qq.com
韶华轻负
jia***ihua77@163.com
对于重写和重载的一些浅薄认识。
重写:我从我的父亲继承了一个中餐馆,但是我觉得中餐馆不够,于是我又在中餐馆的基础上加了个西餐馆。
餐厅还是那个餐厅,只是我继承过来加入了自己独有的方法。
重载:本来我只开了一个赣菜馆,但是我觉得菜系不够,于是我又增加了川菜、粤菜....
做饭的方法并没有改变,只是参数不同,返回的值也不一样。
韶华轻负
jia***ihua77@163.com
alittlemc
ali***emc@189.cn
重载:同名方法通过传入的参数不同(如类型、个数、排序方式)而区分不同方法\函数,与返回值无关
对象:类内的方法之间
例子:void a();void a(int i);int a(String str)等等,关键在传入的参数
重写:在子类中编写与父类 返回值类型相同的同名方法 ,这样原来的父类方法就会被隐藏掉,可以使用super.方法名() 调用
对象:父类和子类之间
可能有错误和不足,仅供参考
alittlemc
ali***emc@189.cn
aojiaodexiaoyanga
259***1569@qq.com
继承:我有一钱包,钱包里面有一张农行卡,有1000元现金,小明找我借钱包,我把钱包给他,他可以用里面所有的东西。
重写和重载:(取钱为例)
重写:小明从我的农行卡中取出100,而我本来要取1000。
重载:去相同的钱,我选择农业银行,而小明却跑去隔壁的建设银行取钱
aojiaodexiaoyanga
259***1569@qq.com