4.2.6多态的实现机制是什么
多态是面向对象程序设计中代码重用的一个重要机制,它表示当同一个操作作用在不同对象时,会有不同的语义,从而产生不同的结果。
在Java中,多态主要有以下两种表现方式:
1>方法的重载(overload)。重载是指同一个类中有多个同名的方法,但这些方法有着不同的参数,因此在编译时就可以确定到底调用哪个方法,它是一种编译时多态。重载可以被看做一个类中的方法多态性。
2>方法的覆盖(override)。子类可以覆盖(重写)父类的方法,因此同样的方法会在父类与子类中有着不同的表现形式。在Java语言中,基类的引用变量不仅可以指向基类的实例对象,也可以指向其子类的实例对象。同样,接口的引用变量也可以指向其实现类的实例对象。而程序调用的方法在运行期才动态绑定(绑定指的是将一个方法调用和一个方法主体连接到一起),就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。通过这种动态绑定的方法实现了多态。由于只有在运行时才能确定调用哪个方法,因此通过方法重写实现的多态也可以被称为运行时多态。
代码如下:
class Base{
public Base(){
g();
}
public void f(){
System.out.println("Base f()");
}
public void g(){
System.out.println("Base g()");
}
}
class Derived extends Base{
public Derived(){
System.out.println("Derived Structor!");
}
public void f(){
System.out.println("Derived f()");
}
public void g(){
System.out.println("Derived g()");
}
}
public class Polymorphic {
public static void main(String[] args){
Base b = new Derived();
b.f();
b.g();
}
}
运行结果如下:
Derived g()
Derived Structor!
Derived f()
Derived g()
根据运行结果可以看到Base b = new Derived;语句调用了两个方法,首先调用了父类Base的构造器Base(),然后调用了子类Derived的构造器Derived()。这里为什么会这样呢?这是因为Derived类继承了Base类,D的构造函数里面就会隐式的有一个super(),代表了父类的构造函数,这时候父类的构造函数调用了g()方法,但是由于这时候是向上转型,此时的子类会忘记它和父类不同的方法,重写父类中的方法,所以,调用的g()方法就已经被子类重写过了;然后调用子类的构造方法Derived()。
这时候就可以理解后面两条语句为什么是Base类名.方法却调用了Derived类的方法,就是因为向上转型时的方法重写。 (关于子类调用父类的构造器) (关于实现多态时的向上转型)