使用interface声明时,无法调用子类中新添加的方法

时间:2017-04-28 09:06:25

标签: java generics inheritance

我扩展了ArrayList并尝试实现增强的ArrayList。所以我在ArrayList的这个子类中添加了几个函数,如下所示:

public class NiceList<T extends Comparable<T>> extends ArrayList<T> {

    public boolean someNewMethods() {

        // balh blah blah...
    }
}

然后我使用NiceList接口类型声明一个新的List对象:

List<String> test = new NiceList<>();

但后来我发现我为NiceList编写的这些方法无法使用刚刚创建的对象test调用:

test.someNewMethods(); // cannot resolve method someNewMethods()

这是否暗示:只要您尝试使用接口作为声明类型来使您的程序更通用,您只能使用那个接口中定义(或要求覆盖)的方法?为什么?你们能为我提供任何参考资料吗?是否有任何解决方法可以使我的程序更通用?

先谢谢你们。

======================================

赞赏!现在我觉得我真的理解界面知识的概念。

2 个答案:

答案 0 :(得分:1)

  

只要您尝试使用interface作为声明类型来使您的程序更通用,您只能使用在该接口中定义的那些方法吗?

  

为什么会这样?

因为编译器看到&#39;只有声明类型的公共API 而不是运行时类型。您必须将实例强制转换为定义要访问的方法的类型。

  

是否有任何解决方法可以使我的程序更通用?

只要您想使用List类型,答案就是。如果您愿意使用MyList<T> extends List<T>这样的新类型,则必须在您希望访问新方法的任何地方使用MyList

答案 1 :(得分:0)

变量的声明类型可以在编译时确定您可以在此变量上调用的方法(无需向下转换)。

如果您声明List变量,则可以调用List的方法 如果您声明NiceList变量,则可以调用NiceList

的方法
  

是否有任何解决方法可以使我的程序更通用?

它很广泛,但要保持与java.util.List接口最兼容,您应该在不需要List特定性的方法和类中声明并传递NiceList个对象,并声明{ {1}}仅在需要时才使用 如果不需要,您还可以避免在客户端代码中的任何地方泄露NiceList类型。

但显然,它可能很快变得棘手而且难以尊重 引入一个不继承NiceList但是组合它的包装类应该更好,因为你在包装器中用ArrayList隔离了耦合,你不需要再尝试符合{{ 1}} interface。