2013-11-04 83 views
0

我正在學習Java SE 7認證考試,我正在做一些關於繼承和訪問修飾符無聊的練習。奇怪的行爲擴展抽象類(練習)

但現在我得到了一個應用繼承的意外行爲。在我基礎包com.testpkg我有一個抽象類:

package com.testpkg; 

public abstract class Abstract { 

    public int test(); 

} 

注意我自願省略了abstract修改爲test()方法。

然後我在包com.testpkg.sub延伸Abstract的具體類:

package com.testpkg.sub; 

public class Concrete extends Abstract { 

    public int test() { 
     return 0; 
    } 
} 

我使用測試這個類:

package com.testpkg; 

import com.testpkg.sub.Concrete; 

public class TestMain { 

    public static void main(String[] args) { 
     Abstract c = new Concrete(); 
     System.out.println(c.test()); 
    } 
} 

如果我嘗試編譯此,我明明得到兩個錯誤:

The method test() requires a body instead of a semicolon 

但是我f我運行測試課:0被打印在控制檯上!

這對我來說似乎很奇怪。你能解釋爲什麼代碼在工作,即使在Abstract類中錯誤地聲明test()

注意我正在使用Eclipse IDE編譯/運行我的代碼。

+0

如果代碼沒有編譯,它的運行情況如何? – Boj

+1

@我正在使用Eclipse。它提醒編譯錯誤存在,但允許我運行代碼。 – davioooh

+0

我相信這就是你的問題的答案。 Eclipse允許您運行「半打」代碼。這裏運行良好的原因是因爲在運行時你永遠不會真正依賴'Abstract'類的細節,所以如果你有這種類型的編譯錯誤並不重要。 – aioobe

回答

1

Eclipse允許您運行「半成品」代碼。這裏運行正常的原因是,在運行時,你永遠不會真正依賴Abstract類的細節,所以如果你有這種類型的編譯錯誤並不重要。

+1

非常感謝! – davioooh

+1

@aioobe:你的意思是「半焙」的代碼? Eclipse使用javac編譯代碼,並且javac不會生成其中包含此錯誤的類文件。如果我在eclipse中創建這三個文件,則抽象類沒有任何類文件。如果我嘗試運行主類,它說「線程中的異常」主「java.lang.Error:未解決的編譯問題」,並且不運行。我相信OP有一個抽象類的類文件,我不相信javac(或者eclipse,不過是魔術)爲它生成了這個錯誤。 – arcy

+1

no no。 Eclipse有它自己的編譯器。運行帶有編譯錯誤的程序是其特色之一。看到[這個答案](http://stackoverflow.com/questions/3061654/what-is-the-difference-between-javac-and-the-eclipse-compiler)例如。 – aioobe

0

你的類Abstract有編譯錯誤,因爲應該定義非抽象方法,所以它應該有一個主體。 abstract只有在接口的情況下,限定符纔是可選的。

+1

正如我在我的問題中寫的,我自願忽略了test()方法的抽象修飾符。問題是即使存在錯誤,代碼仍然正常工作... – davioooh

2

您需要在test()方法中使用abstract限定符。您可能會運行舊的類文件。如果將return語句的值更改爲0以外的內容,則會看到它沒有運行此代碼。

+1

不幸的是,這不是真的。我用不同的返回值更新了我的代碼,總是返回正確的值。嘗試一下! – davioooh

+0

那麼,在我的系統上,由於抽象類中存在編譯錯誤,因此編譯器不會創建類文件(我嘗試過驗證它)。由於抽象類沒有類文件,程序將不會運行。我猜你已經有了一個神奇的編譯器來創建類文件,即使它告訴你有錯誤。聽起來像一個令人興奮的工作環境,無法確定編譯是否發生,並猜測它是如何產生的。或者抽象類仍然有一箇舊的類文件,並且改變具體類中的值會繼續使用它。 – arcy

+0

沒有'神奇的工作環境'...只是日食 – davioooh