重载(Overloading)和重写(Overriding)是Java中两个重要概念。
定义
重载:指在同一个类中,多个函数或方法有同样的名称,但参数列表不相同的情况。这样的同名不同参数的函数或者方法间,互称为重载函数或方法。
重写:指的是在Java的子类与父类中有两个名称、参数列表都相同的方法的情况。由于他们具有相同的方法签名,所以子类中的新方法将覆盖父类中原有方法。
重载例子
class Dog{
public void bark(){
System.out.println("woof ");
}
//overloading method
public void bark(int num){
for(int i=0; i<num; i++)
System.out.println("woof ");
}
}
上面代码中,定义了两个bark方法,一个没有参数的bark方法,另一个是包含int类型参数的bark方法。我们就可以说这两个方法是重载方法,因为他们的方法名相同,参数列表不同。
在编译期,编译期可根据方法签名(方法名和参数情况)情况确定是哪个bark方法被调用。
方法重载需要具备以下条件和要求:
1、被重载的方法必须改变参数列表;
2、被重载的方法可以改变返回类型;
3、被重载的方法可以改变访问修饰符;
4、被重载的方法可以声明新的或更广的检查异常;
5、方法能够在同一个类中或在一个子类中被重载。
重写例子
class Dog{
public void bark(){
System.out.println("woof ");
}
}
class Hound extends Dog{
public void bark(){
System.out.println("bowl");
}
}
public class OverridingTest{
public static void main(String [] args){
Dog dog = new Hound();
dog.bark();
}
}
上面代码中,分别在父类、子类中定义了bark方法,且他们都是无参方法,所以我们就说这种情况是方法重写。即子类Hound重写父类Gog中的bark方法。
在代码main方法中,dog
对象被定义为Dog
类型。
在编译期,编译器会检查Dog类中是否有可访问bark()
方法,只要包含bark()
方法,就编译通过。
在运行期,Hound
对象被new
出来,并赋值给dog
变量,这时,JVM明确知道dog
变量指向的是Hound
对象的引用。所以,当dog
调用bark()
方法时,会调用Hound
类中定义的bark()
方法。这就是所谓的动态多态性。
方法重写的条件需要具备以下条件和要求:
1、参数列表必须完全与被重写方法相同;
2、返回类型必须完全与被重写方法返回类型相同;
3、访问级别的限制性一定不能比被重写方法的强;
4、访问级别的限制性可以比被重写方法的弱;
5、重写方法一定不能抛出新的检查异常或比被重写的方法声明的检查异常更广泛的检查异常;
6、重写的方法能够抛出更少或更有限的异常(也就是说,被重写的方法声明了异常,但重写的方法可以什么也不声明);
7、不能重写被标示为final方法;
8、如果不能继承一个方法,则不能重写这个方法。
重载(Overload)和重写(Override)的区别?
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;
重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。
重载对返回类型没有特殊的要求,不能根据返回类型进行区分。