“类型未定义的方法”错误,与upcast一起使用 - 发生了什么?

时间:2013-03-27 22:26:27

标签: java inheritance

这让我感到难过:)代码正在运作,因此它更像是一种心理挑战。我正在尝试在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");

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

1 个答案:

答案 0 :(得分:3)

Composite扩展UIObject Tab。您的引用是Tab对象,而不是ClickDelegatePanelComposite,因此是UIObject)。 Tab接口不声明addStyleName,这是Eclipse告诉你的。你发生能够在这里成功地将Tab转换为UIObject,但是类型层次结构无法保证 - 我可以编写一个实现Tab的类,它不是UIObject。在这种情况下,演员会失败。