1

这让我很难过 :) 代码正在运行,所以这更像是一个心理挑战。我正在尝试在 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 {

添加样式的方法是addStyleName,它由 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 甚至意识到了这一点,并提供了一个快速修复建议,该建议可以进行更临时的向上转换......

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

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

4

1 回答 1

3

Composite扩展UIObject不是 Tab。您的引用是一个Tab对象,而不是 a ClickDelegatePanel(这是 a Composite,因此是 a UIObject)。Tab 接口没有声明 addStyleName,这是 Eclipse 告诉您的。您碰巧能够在这里成功地将 Tab 转换为 UIObject,但这并不能由类型层次结构保证——我可以编写一个实现 Tab 的类,它不是 UIObject。在这种情况下,演员阵容将失败。

于 2013-03-27T22:31:55.027 回答