【问题标题】:java declare a method in a implementing class and not in the interfacejava在实现类中声明一个方法,而不是在接口中
【发布时间】:2012-09-22 18:20:43
【问题描述】:

首先,我在 Java 方面的经验很少。

回答我的问题,我正在用我自己的方法实现我自己的列表。

 public class MyList<E> implements List<E>{

 private Node<E> head;

 private static class Node<E> {
     private E element; 
     .....
 }

现在,这个类中有一个方法可以将此列表与给定的列表进行比较:

public boolean equals(List<E> list){
....
}

要启动此方法,首先我们必须获取列表的头部,然后我可以访问元素并比较列表。
现在,我们没有 getHead() 方法。 因此,我们尝试在实现类中创建以下方法

public Node<E> getHead(){    

编译器找不到符号。当然,我们需要先在接口中声明它。问题是,如果我们尝试这样做,接口不知道 Node 是什么。 所以我在这里陷入僵局。

我得到错误:

  Cannot find symbol
  symbol  : method getHead()
  location: interface List<E>
    Node<E> lhead = list.getHead();

我希望它使 getHead 成为特定于实现的方法。我怎么做?

请问,可以把implementation中的internal class移到interface中吗? 不知道如何解决这个问题,

感谢您的宝贵时间

【问题讨论】:

  • 你想把那个方法放在哪里?对我来说编译得很好
  • 为什么getHead() 不返回E
  • @MattBall 什么? headNode&lt;E&gt; 的一个实例,所以 getHead 应该返回 Node&lt;E&gt;,不是吗?
  • @Alex Coleman 我试图把它放在实现类中。问题是,当我使用 getHead 时,它说找不到符号。
  • public boolean equals(List&lt;E&gt; list){ 通常 equals 方法看起来不是那样的。参数类型为Object。它重载了方法public boolean equals(Object object){。尝试使用 @Override 注释。

标签: java methods interface implementation


【解决方案1】:

您是在实现java.util.List 还是您创建的一些自定义List 接口?如果你使用的是标准类,当然不能修改核心JDK类。

如果你有一个自定义的List 接口,我发现几个问题:

  • 您的equals() 方法应该接受Object 并向下转换。否则你是在重载而不是覆盖

    public boolean equals(Object obj) {
      //check type first
      List<E> list = (List<E>)obj;
    
  • Node 类是在 MyList 内部私下定义的。将其放入您的List 界面,即可公开访问。

  • 最后,您通常根据内容而不是表示来定义 equals()。您可能有多个List 实现,只要它们以相同的顺序保存相同的数据,列表就应该被视为相等。在您的实现中,只有使用 head 抽象的列表是相等的。不要依赖getHead(),而是使用迭代器并逐个比较项目。

【讨论】:

    【解决方案2】:

    getHead() 是一个特定于实现的方法,它不属于接口。但这也意味着你不能把它作为接口的一部分来使用,你必须把它作为实现类的方法来调用:

    List<String> myList = new MyList<String>();
    myList.getHead() // Wrong. Compiler error.
    
    MyList<String> myList = new MyList<String>();
    myList.getHead() // Works :)
    List<String> asList = myList; // If you want to work with a List from now on
    

    在您的情况下,还有equals 需要采用Object 的问题,这意味着如果您需要使用特定于实现的(甚至是List-特定的),则需要进行类型检查) 方法:

    public boolean equals(Object o)
    
        if (o == this)
            return true;
    
        if( o instanceof MyList<E> ){
            MyList<E> myList = (MyList<E>)o;
            // do MyList stuff here ...
    
        }
        // Things to do if you're comparing something that isn't a `MyList`
        // go here
    }
    

    【讨论】:

    • 好吧好吧让我试试。因为就是这样,它是一个特定于实现的方法,并且由于某种原因没有编译。
    • 问题是我需要在方法中使用 getHead
    【解决方案3】:

    只是出于好奇,但您的列表类应该有一个 int getSize()E get(int index) 方法(这通常在列表中可用)。 现在,您可以检查大小是否相等,如果是,您可以遍历列表并逐个元素进行比较(使用E get(int index) 方法)。

    编辑:参考实现

    public boolean equals(List<E> other) {
        boolean equal = (getSize() == other.getSize());
        for(int i = 0; i < getSize() && equal; i++) {
            equal = get(i).equals(other.get(i));
        }
        return equal;
    }
    

    【讨论】:

    • 我确实有 getSize。但我需要 gethead 才能进行比较。由于某种原因没有编译
    • 我不太了解 getHead() 方法的目的,因为无论如何您都需要遍历所有元素来比较它们。实际上,您可以使用 get(...) 方法遍历列表并比较元素本身。
    • 是的,但我必须比较头部内部的元素,如何在没有 getHead 的情况下访问另一个列表的头部?
    • @Alessandroempire:我添加了我的意思的参考实现!
    • 是的,但因此您有 get() 方法,该方法应返回所要求索引处的元素。如果索引为 0,它应该返回第一个元素,即头部(如果有元素)。得到(0)=头! get(1) = head.next,以此类推
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 2011-03-23
    • 1970-01-01
    • 2013-05-05
    • 1970-01-01
    • 2014-02-02
    • 1970-01-01
    相关资源
    最近更新 更多