重载(Overloading)和重写(Overriding)是面向对象编程中两个重要的概念,它们在实现多态性时起着关键作用,但两者之间有明显的区别:
- 定义上的区别:
- 重载(Overloading) 指的是在同一个类中可以有多个方法名相同,但这些方法的参数列表(参数的个数、类型或顺序)不同,或者是方法的返回类型在Java中对此并不影响重载,但其他语言如C++中重载还可以基于返回类型的不同。重载是编译时多态(静态多态)的一个体现。
- 重写(Overriding) 发生在子类和父类之间,子类定义了一个与父类中同名、同参数列表、同返回类型的方法,并且访问权限不能低于父类中的方法。重写是运行时多态(动态多态)的一个重要体现,需父类方法使用
virtual
(C++)或不加访问修饰符(Java中默认为 virtual
)。
- 规则上的区别:
- 重载 的方法可以有不同的返回类型,可以有不同的访问修饰符(尽管通常最好保持一致),并且可以抛出不同的异常类型。
- 重写 的方法必须与父类方法有相同的返回类型(或者是其子类型,但通常遵循协变返回类型原则),访问修饰符的限制必须大于等于父类(即不能比父类更严格),且不能抛出新的检查异常或者比父类方法声明的异常更广泛的检查型异常。
- 类的关系上的区别:
- 重载 是同一个类内部方法之间的关系,是一种横向扩展,体现了类接口的多样性。
- 重写 是子类与父类之间的一种关系,是一种纵向的替换或特化,体现了类行为的继承与变化。
- 发生时机上的区别:
- 重载 是编译时决定的,由编译器根据调用方法时提供的参数类型和数量来选择正确的方法版本。
- 重写 是在运行时根据对象的实际类型来决定调用哪个方法,这是通过动态绑定(或称为晚期绑定)实现的。
重载:必须有不同的参数列表;可以有不同的访问修饰符;可以抛出不同的异常;
重写:参数列表必须要与被重写的相同;返回的类型必须保持一致;修饰符和抛出的异常不能在被重写的方法之外
重写是父类与子类的关系,是垂直关系;重载是同一个类方法中的关系,是水平关系。
总结:
1.定义:重载是在同一个类中定义多个具有相同名称但不同参数的方法;重写是子类对父类中已有方法的重新实现。
2.参数列表:重载方法的参数列表必须不同;重写方法的参数列表必须相同。
3.绑定时机:重载是在编译时静态绑定;重写是在运行时动态绑定。
4.所属关系:重载方法在同一个类中;重写方法是子类对父类的方法进行重写。
5.重载:在同一个类中,当方法名相同,形参列表不同的时候 多个方法构成了重载,与修饰符无关,与返回值无关;与抛出异常无关;
6.方法重写:父子类、接口和实现类之间的关系,子类可以重写父类方法,但是参数个数、类型、返回值必须相同。