簡體   English   中英

java如何知道要返回接口的哪個實現對象?

[英]How does java get to know which implementation object of interface to return?

回答時請保持謙虛,我不是Java開發人員(或一般開發人員)

在嘗試使用Java進行xml解析時,我遇到了以下問題-

NodeList nodelist = document.getElementsByTagName("item");

在這里,xml dom對象讓我根據我提供的標簽名稱收集所有對象,但是返回類型是一個稱為-nodelist的接口。 由於無法實例化接口,這令我有些驚訝。

保持斷點並調試代碼,我意識到我實際上為實現NodeList接口的類DeepNodeListImpl獲取了對象。

這是怎么發生的? Java如何知道如何在上面聲明的語句中返回由我的接口“ object”持有的“某些實現”的對象。

還有一件事-在閱讀Java API時,我發現IIOMetadataNode實現了NodeList,但是我之前的代碼片段沒有使我成為IIOMetadataNode類型的對象

很好的問題。

Java不知道要返回對象的哪個實現。

在您的問題中,您引用Document類及其getElementsByTagName方法。 文檔是一個接口,這意味着它本身沒有實現代碼。

因此,實現Document接口的任何人都可以選擇所有詳細信息(包括要從getElementsByTagName方法返回的NodeList實現)。

在getElementByTagName的代碼中,會有類似

NodeList nodeList = new DeepNodeListImpl();
// do something with nodeList
return nodeList;

Java“知道”使用這種類型,因為該方法的代碼將明確選擇實現。

方法總是可以返回它所承諾返回的子類,通常,任何值在運行時都可以是它聲明為的類型的子類型。

因此,getElementsByTagName的實現者可以自由返回DeepNodeListImpl類型的DeepNodeListImpl ,只要它是NodeList的子類型即可。

這是面向對象編程的功能。 類可以擴展基類(或實現接口)。 然后可以將基類或已實現的接口用作“公分母”。 這意味着:返回某種類型的對象的方法實際上可以返回從該類型派生的任何類的對象。

這就是您的情況。 您也不需要真正使用的實際類-您可以使用接口提供的任何方法。

而且,除了接口類型之外,您不應對返回的類型做任何假設。 僅當您100%絕對確定可以轉換為特殊類型時。 示例:如果您現在進行了對DeepNodeListImpl ,但是XML解析器的實現已更改,則如果該實現不再返回DeepNodeListImpl或派生類之一,則可能會在DeepNodeListImpl期間遇到異常。

這是現實生活中的類比。 假設您與一家公司簽約,請您派一名園丁。

您期望得到的是一個可以修剪草坪並修剪籬笆的園丁(園丁界面)。

您得到的是一個真實的人,可能是男人,女人,老少皆宜,並且可能會做與園藝無關的事情,例如准備晚餐(實現烹飪界面),但至少可以修剪草坪並修剪樹籬(實現園丁界面)。

公司負責確定獲得的實施方案(公司扮演“抽象工廠”的角色)。

通常,您並不關心此實現可以執行的與園藝無關的事情。

但是,如果您知道自己的園丁可以做飯,並且想讓園丁准備晚餐,那么您需要將園丁投下廚:

Gardener gardener = AbstractFactory.getGardener();
gardener.mowLawn();
// cast 
Cook cook = (Cook) gardener;
cook.prepareDinner();

請注意,這繞過了AbstractFactory提供的抽象(並因此隱藏了信息):您要求園丁,而不應該在意其他技能。 這樣的結果是,如果您將來開始使用其他工廠,則可能會遇到不能做飯的園丁,並且您的演員表將在運行時導致ClassCastException(您的晚餐可能會感到可怕)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM