2012-04-12 101 views
-2

所以我有一個看起來類似於這樣一個問題:預期的「超類「)的子類克(」Java的超類實例調用子類的方法,不知道爲什麼

package com.blah.A_package; 

public class A 
{ 
    public void f() { 
     g(); 
    } 

    protected void g() { 
     System.out.println("superclass g()"); 
    } 
} 

package com.blah.B_package; 

public class B extends com.blah.A_package.A 
{ 
    protected void g() { 
     System.out.println("subclass g()"); 
    } 
} 

public static void main(String[] args) 
{ 
    A scratch = new A(); 
    scratch.f(); 
} 

運行時,它打印出來,而不是G()」。

我們實際上正在創建超類和子類的對象(這是通過在jar上反射),將它們粘在地圖上,然後在需要時將它們拉出來,但我們通過打印出來進行了驗證object.getClass()。getName()並且看到我們實際上正在處理超類的實例化。

無論如何,當我們運行應用程序時,出於某種原因它使用方法的子類副本而不是超類,儘管該對象是超類的實例化(即,它甚至不應該知道子類的方法)。這是我和我的同事不知道的已知事情嗎?我們完全被困在爲什麼會發生這種情況。

+1

你正在讓一個類擴展一個包?我以前從未見過! – CodeBlue 2012-04-12 19:56:35

+1

這是完全不可運行的java。函數返回類型在哪裏? – ControlAltDel 2012-04-12 19:56:36

+0

你的代碼在很多方面都是錯誤的,請先糾正它們:) – fixmycode 2012-04-12 19:57:21

回答

0

簡而言之,唯一可導致此問題的是運行時對象是B的一個實例,但是您將其聲明爲A.在調用方法時,您的程序將開始查看運行時類它被調用的對象,然後在繼承樹上工作。

在附註中,您缺少構造函數,您的類B擴展了包,並且您的方法沒有返回類型。這是完全無效的Java。

+0

我知道這個例子中存在的問題。這不是實際的代碼。請忽略它們並專注於實際發生了什麼問題。 正如我所說的,我們已經通過打印obj.getClass()。getName()驗證它不是子類的實例。 – Luminoth 2012-04-12 20:01:24

+0

我感冒了,對不起,我剛剛沒有聞到。 – MarioDS 2012-04-12 20:04:58

0

有一件事情,可能會導致混亂由具有B一個子類具有相同的名稱作爲它的超(A)在不同的包用包A超類的一個類似的名稱

除此之外,它看起來像一個分析錯誤。追溯你的步驟。一些想法:刪除類B或使其無法實現,然後重新引入並再次測試。

+0

B沒有子類,B是A的唯一子類。我們用obj.getClass()。getName()打印出完整的類名,它是正在使用的有問題的超類,而不是其他包中的子類或某個類。 – Luminoth 2012-04-12 20:07:35

+0

然後擊敗我... – 2012-04-12 20:08:11

+0

但是在你的分析中它仍然看起來像一個錯誤。追溯你的步驟。一些想法:刪除「B」類或使其無法實現,然後重新引入並再次測試。 – 2012-04-12 20:11:12

相關問題