2015-04-02 68 views
2

的差I有如下的java代碼:上溯造型對象 - 靜態和非靜電型

class A { 
int someMethod() { return 1; } 
int someMethod (A a) { return 2; } 
int someMethod (B b) { return 3; } 
int someMethod (C c) { return 4; } 
static A anotherMethod (Object obj) { return (A) obj; } 
} 

class B extends A { 
int someMethod() { return 6; } 
int someMethod (A a) { return 7; } 
int someMethod (B b) { return 8; } 
int someMethod (C c) { return 9; } 
static A anotherMethod (Object obj) { return (B) obj; } 
} 

class C extends A { 
int someMethod() { return 11; } 
int someMethod (A a) { return 12; } 
int someMethod (B b) { return 13; } 
int someMethod (C c) { return 14; } 
static C anotherMethod (Object obj) { return (C) obj; } 
} 

public static void main (String [] args){ 
A a = new A(); B b = new B(); C c = new C(); 
System .out. println (A. anotherMethod (b). someMethod (b)); 
} 

如所預期的輸出是8

確定現在我刪除的someMethod(B B)中A級:

class A { 
int someMethod() { return 1; } 
int someMethod (A a) { return 2; } 
int someMethod (C c) { return 4; } 
static A anotherMethod (Object obj) { return (A) obj; } 
} 

我討論與我的朋友的輸出,但沒有人能夠解釋到底爲什麼我們得到了一個7作爲輸出現在????!?!

+0

C類在哪裏? – Touchstone 2015-04-02 08:39:34

+0

您是否知道您無法重寫'static'方法?你有什麼是語法上有效的,但'靜態'方法*不會互相覆蓋。 – JonK 2015-04-02 08:45:00

回答

3

這是因爲這個片段:

A.anotherMethod(b) 

給你鍵入的對象A。然後您可以撥打:

.someMethod(b) 

該實例。現在,看到A類不再有someMethod(B b)方法,它將調用someMethod(A a) - 它可以這樣做,因爲BA的一個子類。

因爲你呼籲方法的實例實際上是B型和B類覆蓋someMethod(A a)就是這樣結束了被稱爲一個,因此你的7

0

這是因爲您首先將B對象投射到A,然後在變量b中引用類型A,並且當您將b傳遞給方法時,您真正傳遞的是對A的引用。

A.anotherMethod (b) // Casts and returns a reference of type A. 
.someMethod(b) // What you really have here is a reference of type A 

所以這將調用的someMethod(A一),因此將輸出7.

0

如果更簡單的方式代碼相同的情況下,那麼一切都變得清晰:

public class Playground { 

public static void main(String[] args) throws Exception { 
    B b = new B(); 
    A casted = (A) b; 
    System.out.println(casted.someMethod(b)); 
} 

} 

class A { 
int someMethod(A a) { return 2; } 
int someMethod(B b) { return 3; } 
} 

class B extends A { 
int someMethod(A a) { return 7; } 
int someMethod(B b) { return 8; } 
} 

因此,我們得到了「鑄造」對象,它是B的實例,但鑄造到A.當我們調用someMethod(b),JVM拿起A.someMethod(B b)並執行其被覆蓋的版本。如果沒有呈現A.someMethod(B b),則JVM選取A.someMethod(A a)並執行其覆蓋版本。