方法的重写Overriding和重载Overloading是Java多态性的不同表现。
重写Overriding是父类与子类之间多态性的一种表现,如果在子类中定义某方法与其父类有相同的名称和参数,且方法的返回值类型与抛出异常的类型各自与父类的一致,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。
重载Overloading是一个类中多态性的一种表现。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。
另外:static,native及synchronized方法不能被重写.
如果你认为重写只是在子类中简单的替换了一个方法,你就很容易认为static 方法也能 被重写。事实上,我有很多包含们举例指明static 方法能被重写的代码的邮件。然而,这 些并没有考虑方法重写在运行时决定哪个版本的方法被调用的细节问题。下面的代码似乎表 明static 方法是怎样被重写的。
class Base {
static void amethod() {
System.out.println("Base.amethod");
}
}
public class Cravengib extends Base {
public static void main(String arg[]) {
Cravengib cg = new Cravengib();
cg.amethod();
}
static void amethod() {
System.out.println("Cravengib.amethod");
}
}
如果你编译并运行这段代码,你会发现输出文本Cravengib.amethod,这似乎很好的指 明了重写。然而,对于重写,还有相对于在子类中使用一个方法简单替换另一个方法更多的 东西。还有运行时决定的方法基于引用的类的类型的问题,这可以通过创建正在被实例化的 类的引用类型(实例初始化语句的左半部分)来说明。 在上面的例子中,因为名字叫amethod 的方法与类发生了关联,而不是与特定的类的实 例相关联,它不在乎什么类型的类正在创建它,而仅仅在意用的类型。因此,如果你在调 用amethod 前改变一下这一行,
Base cg= new Cravengib()
你就会发现当你运行程序时,你会得到输出:Base.amethod cg 是一个类Cravengib 在内存中的一个Base 类型的实例的引用(或者指针)。如果一个static 方法被调用了,JVM 不会检查什么类型正在指向它,它只会调用跟Base 类相关实例。
与上面的情况相对比:当一个方法被重写时,JVM 通过句柄检查正在指向的类的类型, 并调用此类型相关的方法。可以结束这个例子了,如果你将两个版本的amethod 方法改变为 非static,并依然创建类:
Base cg= new Cravengib()
编译并运行上述代码,你会发现amethod 已经被重写了,并且输出Cravengib.amethod。