2011-06-12 46 views
2

我正在讀一本關於java中的數據結構的書,它現在正在討論迭代器。我看到下面的代碼,對我來說這似乎很奇怪。在下面的代碼,AbstractIterator是實現Iterator<E>一個抽象類,UniqueFilterAbstractIterator一個子類,不是抽象的,並且data是一個矢量。我想我不明白在第一行中如何獲取Vector.iterator()方法的輸出並將其轉換爲抽象類。在第1行之後,dataIterator不是抽象類的實例化實例嗎?爲什麼你可以投到一個抽象類

AbstractIterator<String> dataIterator = 
    (AbstractIterator<String>)data.iterator(); 
AbstractIterator<String> ui = new UniqueFilter(dataIterator); 

回答

2

問題是我們正在談論兩種不同的類型。 (運行時)類型的對象和(編譯時)類型的引用。

  1. dataIterator是抽象類型的參考 - 沒關係。
  2. data.iterator()返回一個對象,其類型不是從例如明確的參考,但顯然這是從AbstractIterator<String>繼承的具體類型 - 這是確定
  3. 您可以到B類對象的引用總是分配給一個參考如果B是A的孩子,即使A是抽象(或接口),也是A類型的對象。你其實不需要演員。

所以行後一個dataIterator仍然是AbstractIterator<String>類型的參考,但它是一個實現AbstractIterator<String>一個具體類型的對象的引用。

請記住,在JAVA中所有的對象變量實際上都是引用。

UniqueFilter與此問題無關,btw。

0

繼承意味着IS-A。如果孩子繼承父母,那麼孩子IS-A父母並且可以在任何需要父母的情況下使用。

由於UniqueFilter IS-A AbstractIterator,這意味着你可以施放它就像你的代碼顯示。

爲什麼你不相信JVM?

+0

我想我還是不明白。如果我們用'UniqueFilter'忽略第二行,第一行會發生什麼?什麼類型的對象是'dataIterator'?它不能是一個'AbstractIterator'對象,因爲這是一個抽象類,但這就是演員所暗示的或者我錯過了什麼? – jhlu87 2011-06-12 02:02:04

+0

@ jhlu87:因爲'UniqueFilter'的每個實例也是'AbstractIterator'的一個實例(通過繼承),所以'UniqueFilter'指派給'AbstractFilter'類型的變量是可以的。抽象類的唯一限制是你不能調用'new AbstractIterator'。你可以愉快地調用'new UniqueFilter',因爲子類是* not * abstract。在這個例子中'dataIterator'指向'UniqueFilter'的一個實例(但在編譯時你不知道)。 – 2011-06-12 02:46:04

0

抽象類是一個無法實例化的類。通常它將包含一個或多個也被聲明爲抽象的方法,並且必須由子類實現以使子類具體(與抽象相反),因此能夠被實例化。

UniqueFilterAbstractIterator一個子類(一個抽象類)。由於這是一種IS-A類型的關係,所以不能聲明抽象類的實例。

如果你想創建一個抽象類的實例,首先創建一個具體子類,爲創建一個實例,並使用它。

0

線1之後,是不dataIterator一個抽象類的實例化的實例?

這是一個UniqueFilter的實例,這也使得它的AbstractIterator通過繼承。試圖「實例化抽象類的實例」意味着試圖調用抽象類的構造函數,這是不允許的,這就是這裏沒有發生的事情。

0

從你所描述的事情看,它似乎有一個可以被忽略的假設;這裏返回data.iterator()的實現類型是AbstractIterator<String>的子類。

如果可以做出這樣的假設,那麼第一條語句就會變得很明顯,因爲對象可以合法地類型轉換爲繼承層次結構上的任何對象,在本例中爲AbstractIterator<String>

在這種情況下,dataIterator不是抽象類的實例化實例;它在這裏沒有被實例化(即new AbstractIterator<String(...)),它只是對由Vector.iterator()返回的實例化實例的引用,類型是實際返回類型的超類的類型,這恰好是一個抽象類。

0

HeadofState是一個抽象(由抽象詞的英文意思)術語。

在世界上沒有一個國家的首腦的官方頭銜是國家元首。

一個頭的狀態,即使抽象的語言和存在,是一個超類或類似蘇丹,總統,總理,首相,敬愛的父親頭銜的超級類別等

所以,即使雖然國家元首的存在不能以抽象的形式被實例化,但你可以實例化(通過民主手段,世襲或者政變)總統,總理或者任何不管怎樣的人。

所以說,總理已經實例化,那麼它可以等同於其「國家元首」的抽象父級術語。

因此,即使抽象類不能被實例化,該抽象類的實現也可以被實例化。這是工廠可以做的。工廠是創建抽象類實例的一種手段。

就像抽象類一樣,接口不能實例化,但必須實現。抽象類部分實現,而接口自己完全沒有實現。抽象類和接口依賴於派生類來完成它們的存在。當然,迷戀OO-purist的技術術語會闡明抽象類是「擴展的」,接口是「繼承的」。

例如,HttpServletRequest是一個接口。你不能直接評估它。當您的JSP抓取它的http servlet請求時,無論您在Jetty還是Tomcat中,它的工作原理都是一樣的。但是,如果仔細檢查,Jetty中的HttpServletRequest工廠實例化的實際類與Tomcat中創建的類不同。但是,由於它們都實現HttpServletRequest,所以這些實例可以簡單地等同於類型爲HttpServletRequest的變量。

您應該閱讀抽象類vs接口以及接口如何炮製以允許Java中的僞多重繼承。一旦你理解了接口的作用,你就可以理解抽象類。在面向對象的火焰戰爭領域,有人認爲接口是多重繼承中的一個輝煌的突破。有人認爲接口與多重繼承無關。以我自己的拙見來看,界面是社會主義縱容放縱的一種貧窮而失敗的嘗試,它阻止我陷入麻煩,認爲我不知道如何照顧自己。

相關問題