2010-10-05 125 views
1

如果每個對象都有不同的實例變量副本,那麼方法在哪裏「活着?」方法在哪裏?

作爲一個例子:

class A { 
    public foo() { 
     System.out.println("foo"); 
    } 
} 

class B extends A { 
    public foo() { 
     System.out.println("foofoo"); 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     A a = new B(); 
     a.foo(); // "foofoo" 
    } 
} 

我知道 「foofoo」 被打印。那麼方法是綁定到對象還是什麼?

+0

由於與我用不同語言提出的問題相似,我將在此處鏈接我的問題。 flash和java的區別在於flash是一種基於原型的語言,它可以在運行時發生方法覆蓋,這就是爲什麼我的問題不同。 http://stackoverflow.com/questions/3783256/as2-are-functions-declared-in-a-class-stored-as-separate-instances-taking-up-mor – M2tM 2010-10-05 04:17:45

+0

由於經濟繁華,一大片方法已經離開了其通常的桌子去尋找不那麼迷人的虛擬桌面 – 2010-10-05 04:20:52

回答

3

這通常是一個實現問題。作爲一名Java程序員,您需要關心的是,每個類都可以具有與其他類不同的方法。

在實現方面(如果您對隱藏行爲感興趣),最簡單的解決方案是每個類都有一個指向所有相關函數的指針。

這樣一來,當你與B延長AB類型的實例,將得到所有A的的指針方法,但與foo方法指針指向B的代碼。

的圖形表示,其中B延伸A,只是foo覆蓋:類(對象)的

class A 
    foo ----------> Afoo code 
    bar ----+-----> Abar code 
class B  | 
    bar ----+ 
    foo ----------> Bfoo code 

實例瞭解他們的類型,這樣你可以從對象b獲得容易B類。從那裏,找到正確的代碼來運行是一個簡單的操作。

4

您所指的過程被稱爲動態調度。這通常被實現的方式是通過虛擬表(通常被稱爲虛函數表):

http://en.wikipedia.org/wiki/Virtual_table

的如何的vtables工作的簡單總結的是,每一種方法被存儲在某個存儲器地址,和一個虛函數表存儲這些地址。使用你的例子,A有一個vtable,它的一個條目保存foo版本的內存地址,而子類B有它自己的具有相同佈局的vtable,但它保存了它自己的foo的內存地址。