目录
重载和重写这两个概念:
1、重载是一个编译期概念、重写是一个运行期概念。
2、重载遵循所谓“编译期绑定”,即在编译时根据参数变量的类型判断应该调用哪个方法。
3、重写遵循所谓“运行期绑定”,即在运行的时候,根据引用变量所指向的实际对象的类型来调用方法。
4、Java中的方法重写是Java多态(子类型)的实现方式。而Java中的方法重写其实是特设多态的一种实现方式。
重载(Overloading)和重写(Overriding)是Java中两个比较重要的概念。但是对于新手来说也比较容易混淆,本文就举两个实际的例子,来说明下到底是什么是重写和重载。
定义
重载:指的是在同一个类中,多个函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。
重写:指的是在Java的子类与父类中有两个名称、参数列表都相同的方法的情况。由于他们具有相同的方法签名,所以子类中的新方法将覆盖父类中原有的方法。
重载demo
public class Dog {
public void bark(){
System.out.println("woof");
}
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、方法能够在同一个类中或者在一个子类中被重载。
重写demo
下面是一个重写的例子,看完代码之后不妨猜测一下输出结果:
class dog{
public void bark(){
System.out.println("woof ");
}
}
class Hound extends dog{
public void sniff(){
System.out.println("sniff ");
}
@Override
public void bark(){
System.out.println("bowl");
}
}
测试:
public class Test {
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、如果不能继承一个方法,则不能重写这个方法。
不要灰心,不要绝望,对一切都要乐观……需要有决心——这是最要紧的,有了决心一切困难的事都会变得容易。 ————《人民日报》