运行时多态性是面向对象程序设计代码重用的一个最强大机制,Java多态性的概念也可以被说成“一个接口,多个方法”。Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制。
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。
当一个子类需要调用父类的(已覆盖的)方法,则需要使用超类。在java中,采用this关键字标识自身类的引用,而super关键字则指向所在类的父类。若子类中的test方法已经定义,若要调用父类的test方法,则使用super.test()。若要调用父类的构造方法,则使用super()。
当运行时,调用方法存在重写时,JVM在调用方法时会按照this.funcName(),super.funcName(),而在变量的选择时,会按照this.funcName(var),this.funcName((Super)var)的顺序执行,当高优先级的方法被命中,则执行。
class A
{
public String show()
{
return ("A");
}
}
class B extends A
{
public String show()
{
return ("B");
}
}
public class ExtendAB
{
public static void main(String[] args)
{
A a = new B();
B b = new B();
System.out.println(a.show());
}
}
一个比较容易理解的例子就是toString方法,当在某个地方获取到的类并不知道他的具体类型时,可以将该类的引用定义为Object,此时同样可以调用该类的toString方法,调用是子类而非超类(Object类)的toString方法。
当然,如果一个超类变量引用的对象类型实际上一个子类,当该超类被强制类型转换后,是可以还原其子类的所有方法的。Java在做类型转换时,编译并不会报错,因为编译过程并不能知道该类是否可能被强制转换,若转换失败则抛出ClassCastException