前言
对于Java的基础知识,很多内容都是熟悉又陌生的,总觉得当时是理解了,过一段时间再分享的时候却有些词不达意,说明对于这个知识的理解还是不到位,今天特地记录下来。
问题
1、重写是什么?
2、重载是什么?
3、重载与重写的区别是什么?
4、为什么要把它们两个进行比较?
解答
重写是什么?
子类包含与父类同名方法的现象被称为方法重写(Override),也被称为方法覆盖。
具体可以说是子类将与父类同名方法中的方法体进行重写,但是方法名、参数列表、返回类型都不变。
父类:Bird类
public class Bird
{
// Bird类的fly方法
public void fly(){
System.out.println("我在天空自由自在的飞翔……");
}
}
子类:Ostrich类
public class Ostrich extends Bird
{
// 重写Bird类的fly方法
public void fly(){
System.out.println("我只能在地上奔跑……");
}
public static void main(String[] args){
// 创建Ostrich对象
Ostrich os = new Ostrich();
// 执行Ostrich对象的fly方法,将输出“我只能在地上奔跑……”
os.fly();
}
}
执行上面的程序将看到os.fly()执行时不再执行Bird类的方法,而是执行Ostrich类的fly()方法。
两同两小一大
方法的重写要遵循“两同两小一大”规则。
- 两同:方法名相同,形参列表相同
- 两小:子类方法返回值类型应比父类方法返回值类型小或相等
- 子类方法声明抛出的异常类应比父类方法声明抛出的异常类小或相等
- 一大:子类方法的访问权限应比父类方法的访问权限更大或相等
特性
父类与子类之间的多态性,即在子类中重写该方法——相同方法名,相同参数,不同实现(运行时多态性)。
当子类覆盖了父类方法后,子类的对象将无法访问父类中被覆盖的方法,但可以子类方法中调用父类中被覆盖的方法。——使用super可解决
重载是什么?
Java允许同一个类里定义多个同名方法,只要形参列表不同就行。如果同一个类中包含了两个或两个以上方法的方法名相同,但形参列表不同,则被称为方法重载。
public class Overload
{
// 下面定义两个test()方法,但方法的参数列表不同
public void test(){
System.out.println("无参数");
}
public void test(String msg){
System.out.println("重载的test方法" + msg);
}
public static void main(String[] args){
Overload ol = new Overload();
// 调用test()时没有传入参数,因此系统调用上面没有参数的test()方法
ol.test();
// 调用test()时传入了一个字符串参数
// 因此系统调用上面带一个字符串参数的test()方法
ol.test("abc");
}
}
两同一不同
- 两同:同一个类中方法名相同
- 不同:参数列表不同
至于其他部分,例如方法返回类型等不能作为区分方法重载的方法
为什么呢?
对于int f(){}和void f(){}两个方法,如果这样调用:
int result = f();
系统是知道调用的是哪一个方法,但是Java中调用方法时,是可以省略方法返回值,即这样调用:
f();
这样的话就不能区分到底调用了哪一个方法,人尚且无法区分,系统又怎么能够判断调用哪一个呢?
特性
重载Overload是一个类中多态性的表现——同类同方法名,不同参数列表(编译时多态性)
重写与重载的区别是什么?
方法的重载和重写都是多态性的一种体现,前者是编译时多态性,后者是运行时多态性。
重载发生在同一类中,要求方法名相同,参数列表不同。重载对返回类型没有特殊要求,不能根据返回类型进行区分。
重写则发生在具有父子关系的类中,要求方法名相同,参数相同,具体实现不同。并且对于返回类型和异常抛出以及访问权限均有限制,具体可详见上面描述。
为什么要进行比较?
它们两者本身没有太大的比较意义,除了二者都是发生在方法之间,并要求方法名相同之外,并没有太多的相似之处。但是从多态的角度去思考的话,还有值得我们推敲的内容。
小结
当然,父类方法和子类方法之间也可能发生重载,因为子类会获得父类的方法,如果子类定义了一个与父类方法有相同的方法名,但参数列表不同的方法,就会发生父类与子类之间的方法重载。
参考文章:Java—重写与重载的区别
疯狂Java讲义第4版
感谢您的阅读~~