2012-02-15 97 views
3

我有一個超類:java的覆蓋方法調用

public class SuperClass { 

    public void dosomething() { 
     firstMethod(); 
     secondMethod(); 
    } 

    public void firstMethod() { 
     System.out.println("Super first method"); 
    } 

    public void secondMethod() { 
     System.out.println("Super second method"); 
    } 
} 

一個子類:

public class SubClass extends SuperClass { 

    public void dosomething() { 
     super.dosomething(); 
    } 

    public void firstMethod() { 
     System.out.println("Sub first method"); 
    } 

    public void secondMethod() { 
     System.out.println("Sub second method"); 
    } 
} 

測試類:

public static void main(String[] args) { 
     SubClass sub = new SubClass(); 
     sub.dosomething(); 
     SuperClass sup = new SuperClass(); 
     sup.dosomething() 
} 
當運行測試方法

,我得到了這個:

Sub first method 
Sub second method 

你能告訴我這是怎麼發生的嗎?在子類dosomething方法中,我調用了super.dosomething(),我認爲將調用super方法,但子類中的override方法被調用。

如果我這樣做:
SuperClass superClass = new SuperClass();
superClass.dosomething();


結果爲:
中超第一種方法
超級第二種方法

不同的是方法調用的地方。我覺得一定有什麼東西我不`噸知道!):

哎呀super引用指向第一個例子中的子類...

這樣的:

SuperClass sub = new SubClass();
sub.firstMethod();
sub.secondMethod();

回答

1

您調用方法的對象是SubClass類型,而不是SuperClass類型。即使你調用一個只在SuperClass中定義的方法,你的執行上下文仍然是SubClass。因此,任何被覆蓋的方法都會執行重寫的方法。

從這個事情中解脫出來的是,通過聲明firstMethod和secondMethod爲public,SuperClass實際上允許子類覆蓋它們的行爲。如果這不合適,這些方法應該是私人的或最終的。

+0

我認爲這個功能是非常有用的,但我只是不知道它是如何工作的詳細:( – Felix 2012-02-15 10:12:54

+2

@Felix:什麼不你瞭解它嗎?它是你的對象的運行時類型的重要,而不是變量定義的類型。 – 2012-02-15 14:01:57

3

在java,方法binding總是dynamic [這裏忽略靜態和私有方法]。因此,當您覆蓋firstMethod()secondMethod()時,任何時候​​類型的對象都會嘗試調用其中一個對象 - 即使它的[調用]來自父級的方法,也會調用overriden方法。

因此,正如預期的那樣 - 當您調用super.doSomething()時,它會調用firstMethod()secondMethod(),並調用overriden方法。

+0

「(忽略靜態和私人方法)」 – 2012-02-15 10:00:24

+0

@JoachimSauer:在答案中添加了私人異常。謝謝。 – amit 2012-02-15 10:03:13

1

Super.dosomething()的確在調用Super類中的方法dosomething()。但是在這個方法中,你可以調用firstMethodsecondMethod的函數。這些方法在Sub類中被覆蓋,它們從Sub類中調用。

由於佩塔爾·伊萬諾夫建議:

可以防止它們被重寫,如果你將它們標記爲最終

+0

我們如何調用超類的方法......將'this.firstMethod()'工作,而不是firstMethod()裏面的基類??? doSomeThing().... – aProgrammer 2012-02-15 09:22:50

+1

檢查我的編輯! – 2012-02-15 09:41:26

+0

@aProgrammer它仍然是一樣的。 – Felix 2012-02-15 10:07:20

1

事實上,超級DoSomething的被調用。首先執行一些調用方法和secondMethod,它們是虛擬方法(Java中的任何方法默認是虛擬的,這意味着它可以被重寫)。所以他們的重寫版本被調用。

如果最終標記它們,可以防止它們被覆蓋。