2012-08-06 76 views
2
abstract class A { 

    public void methodA() { 
     System.out.println("methodA"); 
     methodB(); 
     showName(); 
    } 

    public abstract void methodB(); 

    public void showName() { 
     System.out.println("in showname base"); 
    } 
} 

class B extends A { 

    public void methodB() { 
     System.out.println("methodB"); 
    } 

    public void showName() { 
     System.out.println("in showname child"); 
    } 
} 

public class SampleClass { 

    public static void main(String[] args) { 
     A a = new B(); 
     a.methodA(); 
    } 
} 

輸出是:爲什麼按此順序輸出?

了methodA
的methodB
在showname孩子

問題: -

由於覆蓋,對象類型被認爲。這是不是類B的showName()方法被稱爲不是類A的原因?如果不是那麼這個輸出命令的原因是什麼?

+0

請格式化你的代碼。 – 2012-08-06 18:47:08

+0

嘿保羅,我很抱歉,但我不知道如何格式化它。 – Jaikrat 2012-08-06 18:48:44

+0

我們應該在這裏回答關於學校作業氣味的問題嗎? – Steve 2012-08-06 18:49:11

回答

3

這很容易:

A a = new B(); 
    a.methodA(); 

這裏已知的是,是B類的對象,所以從B類使用的每一個可以在B類中重寫方法,如果沒有壓倒一切,然後從類方法必須使用A

考慮順序:

調用methodA聲明爲:

public void methodA() { 
    System.out.println("methodA"); 
    methodB(); 
    showName(); 
} 

methodA()內部調用都methodB()showName()。它們在類B中被覆蓋,而對象a是instanceof B,所以這就是它們(來自B類)的原因。

編輯在評論中提到:

@Jaikrat辛格,B類還是A類(它的孩子,但繼承類型的關係:IS-A)。類B繼承了A類的方法。所以它也有methodA。所以最好說methodA也被稱爲類B,但是默認代碼是 - 類A

+0

但我沒有從任何對象類型調用重寫的方法。該方法是從另一個由於引用類型而被調用的方法的主體中調用的。 – Jaikrat 2012-08-06 18:57:42

+1

@Jaikrat Singh,B類仍然是A類(它的孩子,但繼承是類型的關係:IS-A)。類'B'繼承了'A'類的方法。所以它也有'methodA'。所以,最好是說,那'methodA'也從類'B'稱爲但是是默認代碼 - 同樣在課堂上提供的'A' – dantuch 2012-08-06 19:02:02

2

雖然對象'a'被聲明爲類型A,但它被實例化爲類型B.多態性導致實例類型的方法被調用而不是聲明類型的方法,因爲它是B類型的內部,所以調用類B的showName()方法。

+0

但我不是要求從任何OBJECTTYPE是重寫的方法。該方法是從另一個由於引用類型而被調用的方法的主體中調用的。 – Jaikrat 2012-08-06 18:58:07

+2

雖然了methodA()僅被定義在類A,它仍然通過多態性決定中了methodA(),每個方法調用運行,是因爲showName()在B類的定義,它調用showName(),而不是一個定義在A級。 – Vulcan 2012-08-06 19:02:46

+0

嘿謝謝@Vulcan。我試圖選擇你的答案也是「接受答案」,但我認爲一次只能選擇一個答案。謝謝你澄清我的想法。我很困惑。再次感謝。 – Jaikrat 2012-08-06 19:09:52

4

您創建了一個B類型的對象,因此在該對象上調用的所有方法都將在類B上。如果類B沒有實現某些方法(如methodA),則Java會嘗試在父類中找到一個方法一個)。你應該在面向對象的語言閱讀關於多態性

http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming

+0

最佳答案:解釋多態性。 +1 – Vulcan 2012-08-06 18:57:58

0

你有抽象類A,它是由B延長。延伸相當於B "is a" A。例如,如果蘋果延長水果,apple 'is a' fruit。它像果實一樣行事,但也做蘋果的事情,香蕉不會做。因此B的行爲方式與A相同,但也可以執行其他操作。因此,在您的示例中,您的B將覆蓋兩種方法。每個B對象默認會調用它們。爲了從B訪問A的方法,你需要使用關鍵字super

它是多態性(java編程中的一個關鍵點)的一部分,對象將首先在它自己中找到任何方法(即使它們被父類覆蓋),然後爬上繼承樹以找到方法那不是直接在那個班上。

對於示例:

public void methodA() { 
    System.out.println("methodA"); //This prints no problem. 
    methodB(); //This searches the "B" class for a method called "methodB" If it can't find it, it checks its parent for a "methodB" 
    showName();//This searches the "B" class for a method called "showName" If it can't find it, it checks its parent for a "showName" 
} 

上面的代碼被調用。你知道這麼多(從你做,我假定這一點。其他的評論)一旦行methodB()被調用,您的類型B檢查方法對整個B檔的對象。如果方法不存在,它只會跳到A。然後它會爲showName()做同樣的事情。

2

當您撥打a.methodA()時,由於您的對象類型爲B,因此它會在B中首先查找methodA。由於B中沒有這種方法,因此它會在其超類中尋找此方法,即A。在類A中查找methodA,它將開始執行。

執行,將打印methodA並開始尋找下一個調用的方法(methodB),這是在B類中實現,那麼它將打印methodB

下一個被調用的方法是showName,其在這兩個類實現的。由於Java將開始尋找與對象類型相同的類中的實現,因此它會在第一次嘗試中找到類B

主要規則很簡單:Java將首先嚐試查找對象類型類(在new運算符後面的名稱)中的方法。如果該方法沒有在那裏實現,它將開始通過超類。