在前面的章节中,我们谈到了超类和子类。如果一个类从它的超类继承的方法,则有机会改写,只要它不标记为final的方法。
重载的好处是:定义一个行为是特定于该子类的类型表示一个子类可以实现根据它要求一个父类的方法的能力。
在面向对象的术语,重载表示覆盖现有的方法的功能。
让我们来看一个例子。
class Animal{ public void move(){ System.out.println("Animals can move"); } } class Dog extends Animal{ public void move(){ System.out.println("Dogs can walk and run"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal reference and object Animal b = new Dog(); // Animal reference but Dog object a.move();// runs the method in Animal class b.move();//Runs the method in Dog class } }
这将产生以下结果:
Animals can move Dogs can walk and run
在上面的例子中,可以看到,即使b为一类动物的并运行在狗类中的move方法。这样做的原因是:在编译时,检查是在引用类型。然而,在运行时,JVM计算出的对象类型和运行将属于特定对象的方法。
因此,在上面的例子中,程序将正确编译,因为动物类有法之举。然后,在运行时,它运行的方法,具体用于该对象。
请看下面的例子:
class Animal{ public void move(){ System.out.println("Animals can move"); } } class Dog extends Animal{ public void move(){ System.out.println("Dogs can walk and run"); } public void bark(){ System.out.println("Dogs can bark"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal reference and object Animal b = new Dog(); // Animal reference but Dog object a.move();// runs the method in Animal class b.move();//Runs the method in Dog class b.bark(); } }
这将产生以下结果:
TestDog.java:30: cannot find symbol symbol : method bark() location: class Animal b.bark(); ^
这个程序将抛出一个编译时错误,因为B的引用类型的动物没有一种方法,通过bark的名字。
参数列表应该是完全一样被覆盖的方法。
返回类型应相同或超类中的原重写的方法声明的返回类型的子类型。
访问级别不能比被重写的方法的访问级别更严格。例如:如果父类方法声明为public,在子类中重写的方法不能是private或protected。
实例方法可以被覆盖,只有当他们是由子类继承。
方法声明为final不能被重写。
方法声明为静态的不能被覆盖,但可以重新声明。
如果一个方法不能被继承,那么它不能被重写。
作为实例的父类在同一个包内的子类可以重写未声明为私有的或最终的任何超类方法。
在不同的包中的子类只能重写非final方法声明为public或protected。
重写方法可以抛出任何异常取消勾选,无论重写的方法是否抛出异常与否。但压倒一切的方法不应该抛出checked exceptions新的或不是由重写的方法声明的那些更广泛。重写方法可以抛出比重写的方法较窄或更少的例外。
构造函数不能被重写。
当调用一个重载方法的超类版本,那么需要使用super关键字。
class Animal{ public void move(){ System.out.println("Animals can move"); } } class Dog extends Animal{ public void move(){ super.move(); // invokes the super class method System.out.println("Dogs can walk and run"); } } public class TestDog{ public static void main(String args[]){ Animal b = new Dog(); // Animal reference but Dog object b.move(); //Runs the method in Dog class } }
这将产生以下结果:
Animals can move Dogs can walk and run