2013-03-27 67 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

相关问题