2013-03-27 25 views
1

這讓我難住:)代碼正在工作,所以它更多是一個精神上的挑戰。我試圖在GWT TabBar上設計一個單獨的選項卡。這個小部件的設置有點奇怪--Tab類被定義爲TabBar類中的內部接口,並且它也被稱爲ClickDelegatePanel的TabBar中的內部類實現。的TabBar的完整代碼是在這裏「方法未定義類型」錯誤,適用於upcast - 發生了什麼?

https://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/gwt/user/client/ui/TabBar.java

關鍵位(我想!)是界面..

public interface Tab extends HasAllKeyHandlers, HasClickHandlers, HasWordWrap { 

和實現...

private class ClickDelegatePanel extends Composite implements Tab { 

的添加樣式的方法是由Composite的父項UIObject提供的addStyleName。如果我從TabBar中獲得特定的Tab並嘗試使用此方法,那麼在Eclipse中出現錯誤(並且出現編譯錯誤)。代碼是這樣的......

Tab myTab = tabPanel.getTabBar().getTab(3); 
myTab.addStyleName("gwt-TabBarItem-selected"); 

但是,如果我要上溯造型UIObject的,它的工作原理...

UIObject myTab = (UIObject) tabPanel.getTabBar().getTab(3); 
myTab.addStyleName("gwt-TabBarItem-selected"); 

的Eclipse甚至認識到這一點,並提供快速修復建議,做了更多的臨時上溯造型。 ..

Tab myTab = tabPanel.getTabBar().getTab(3); 
((UIObject) myTab).addStyleName("gwt-TabBarItem-selected"); 

我已經有一個很好的老谷歌,不知道發生了什麼事情。應該不可能完全隱藏超類方法,對吧?任何有關上傳的討論似乎都說它的主要用途是選擇重載方法的超類版本 - 但addStyleName不會重載。我只能假定它與Tab被定義的方式有關,作爲一個內部類實現的內部接口,它擴展了我之後的超類。那麼,這裏發生了什麼?爲什麼使用接口類型阻止我從實現類訪問超類方法?

回答

3

Composite延伸UIObject,不是Tab。您的參考是Tab對象,而不是ClickDelegatePanel(它是Composite,因此也是UIObject)。 Tab界面沒有聲明addStyleName,這是Eclipse告訴你的。你發生能夠在這裏成功地將Tab轉換爲UIObject,但這不是由類型層次結構保證 - 我可以編寫一個實現Tab的類,它不是UIObject。在這種情況下,演員陣容會失敗。

+0

實際上,在這種情況下,您可以將Tab轉換爲ClickDelegatePanel,因爲getTab方法通過Tab接口返回類型返回ClickDelegatePanel對象。 – DiogoSantana 2013-03-27 22:38:01

+1

你可以,但只是因爲你在'欺騙'並且知道'Tab'的具體實現。這是我的觀點 - 編譯器沒有這種類型的信息。另外,你不應該依賴它。對於一個人爲的例子,假設'getTab'變成返回一個'Proxy'標籤,它執行某種延遲加載。該代理將失敗轉換爲ClickDelegatePanel。 – 2013-03-27 22:39:54

+1

我同意,但是當我說「在這種情況下」時,我的意思是這是一個GWT實現,所有類都依賴於實現(TabBar類)。 – DiogoSantana 2013-03-27 22:43:18

相關問題