今天看jcvm的標准的 時候,看到有一個virtual method,感覺很疑惑,以前看Java的時候並沒有發現有這類方法。
百度、Google了一下,才發現,Java中普通方法就是virtual method,動態綁定是Java的默認行為。
如果不想讓一個方法成為virtual method,只要把這個方法申明為final就可以了。
至於在c++中虛方法是怎么回事,可以參考下面這篇文章
http://www.cnblogs.com/xd502djj/archive/2010/09/22/1832912.html
在很多的博客中也有這樣一種說法,Java的virtual method其實就是dynamic binding/dynamic dispatch.
(http://stackoverflow.com/questions/9453701/what-is-virtual-method-calling-in-java)
從這里面的回答可以看出,virtual method就是為了多態而出現的。
下面簡單的介紹一下動態方法調度。
在Java中,如果一個子類的方法和超類的某個方法具有相同的名稱和類型簽名,那么稱子類中的這個方法重寫了超類中相應的方法。
當子類中調用被重寫的方法時,總是調用由子類定義的版本,由超類定義的版本會被隱藏。
方法重寫形成了動態方法調度(dynamic method dispatch)的基礎,動態方法調度可以說是Java中最強大的功能。
動態方法調度室一種機制,通過這種機制可以在運行時,而不是在編譯時解析對重寫方法的調用。
動態方法調度就是Java實現多態的機理所在。
首先申明一點:超類引用變量可以指向子類對象。Java利用這一事實,在運行時解析對重寫方法的調用。
下面是實現原理:
當通過超類引用調用重寫的方法時,Java根據在調用時所引用對象的類型來判斷調用哪個版本的方法。因此,這個決定是在運行時做出的。
如果引用不同類型的對象,就會調用不同版本的方法。
也就是說,是當前正在引用的對象的類型(而不是引用變量的類型)決定了將要執行哪個版本的重寫方法。
例子如下:
public class Test {
public static void main(String[] args){
superTest a = new superTest();
a.eat();
superTest b = new superTest1();
b.eat();
superTest c = new superTest2();
c.eat();
}
}
class superTest{
void eat(){
System.out.println("this is the superTest print");
}
}
class superTest1 extends superTest{
void eat(){
System.out.println("this is the superTest1 print ");
}
}
class superTest2 extends superTest{
void eat(){
System.out.println("this is the superTest2 print");
}
}
最后的輸出結果是:
this is the superTest print
this is the superTest1 print
this is the superTest2 print