这让我感到很沮丧:)代码正在运行,因此这更是一种精神上的挑战。我正在尝试在GWT TabBar上设置单个标签的样式。此小部件的设置有些特殊-Tab类定义为TabBar类内部的内部接口,并且由TabBar中的内部类(称为ClickDelegatePanel)实现。 TabBar的完整代码在这里

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 {


添加样式的方法是addObjectName,它由Composite的父级UIObject提供。如果我从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甚至意识到了这一点,并提供了一个Quick Fix建议,该建议可以进行更临时的转换。

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


我有一个不错的老Google,无法弄清楚发生了什么。不可能完全隐藏超类方法,对吗?关于转换的任何讨论似乎都说它的主要用途是选择一个重载方法的超类版本-但是addStyleName不会重载。我只能假定它与Tab的定义方式有关,它是由内部类实现的内部接口,该内部类扩展了我所追求的超类。那么,这里发生了什么?为什么使用接口类型阻止我从实现类访问超类方法?

最佳答案

Composite扩展了UIObject,而不是Tab。您引用的是Tab对象,而不是ClickDelegatePanel(这是Composite,因此是UIObject)。 Tab接口没有声明addStyleName,这是Eclipse告诉您的。您碰巧能够在此处成功将Tab强制转换为UIObject,但是类型层次结构不能保证这一点-我可以编写一个实现Tab的类,该类不是UIObject。在这种情况下,转换将失败。

10-08 02:33