【问题标题】:Java complains I haven't implemented a methodJava 抱怨我没有实现一个方法
【发布时间】:2011-11-29 09:47:53
【问题描述】:

我有如下界面:

interface IBasicListNode<T> {
  /**
   * Returns the current element
   */
  public T getElement();

  /**
   * Gets the next ListNode. Returns null if theres no next element
   */
  public IBasicListNode<T> getNext();

  /**
   * Sets the next ListNode 
   */
  public void setNext(IBasicListNode<T> node);
}

还有一个班级:

class BasicListNode<T> implements IBasicListNode<T> {
  protected T _elem;
  protected BasicListNode<T> _next;

  public T getElement() {
    return this._elem;
  }

  public BasicListNode<T> getNext() {
    return this._next;
  }

  public void setNext(BasicListNode<T> node) {
    this._next = node;
  }

  /**
   * Transverse through ListNodes until getNext() returns null
   */ 
  public BasicListNode<T> getLast() {
    BasicListNode<T> tmp = this;
    while (tmp != null) {
      tmp = tmp.getNext();
    }
    return tmp;
  }
}

我得到了以下错误:

jiewmeng@JM-PC:/labs/Uni/CS1020/Lab/03/prob 2/LinkedList$ javac BasicListNode.java 
BasicListNode.java:1: BasicListNode is not abstract and does not override 
abstract method setNext(IBasicListNode<T>) in IBasicListNode

class BasicListNode<T> implements IBasicListNode<T> {
^

为什么 java 没有检测到 BasicListNode&lt;T&gt; implements IBasicListNode&lt;T&gt;

【问题讨论】:

  • 请注意,您的 setNext 方法的签名在超类和具体类中是不同的,因此您没有覆盖它。
  • @Yar,我更新了 Interface & Error ,还是不行

标签: java


【解决方案1】:

你在接口类中的setnext()应该是

public void setNext(BasicListNode&lt;T&gt; node);

它缺少在类中实现的参数。更改接口匹配类或类匹配接口,它会停止抱怨。

你的界面应该是:

public interface IBasicListNode<T> {
  /**
   * Returns the current element
   */
  public T getElement();

  /**
   * Gets the next ListNode. Returns null if theres no next element
   */
  public IBasicListNode<T> getNext();

  /**
   * Sets the next ListNode 
   */
  public void setNext(IBasicListNode<T> node);
}

对于你的下一个错误记得放

public前面
public class BasicListNode&lt;t&gt; implements BasicListNodeI&lt;T&gt;

public interface IBasicListNode&lt;T&gt;

【讨论】:

  • 我用更正的界面和新的(但类似的)错误更新了我的帖子
  • 已更新答案,您忘记将 public 添加到类和接口。
  • 好的,我会在公众中添加,我学校的讲师/教职员工在提供“骨架”文件时似乎总是忽略了这一点,为什么?
  • 关于检查是否类似于pastie.org/2629109。然后我想我应该在其他地方抛出一个异常?但是哪一个?无效参数异常?另请注意,我在执行instanceof BasicListNode&lt;T&gt; 时出错,必须使用instanceof BasicListNode,它们是否相同?为什么public BasicListNode&lt;T&gt; getLast() 有效?
  • 假设你的接口和实现类都在同一个包中,它实际上可以在没有 public 修饰符的情况下工作,因为当它被忽略时,它会默认为有时称为包私有并且对都在同一个包中。有关您其他问题的详细信息,请参阅下面的帖子,因为我将在该帖子中添加答案。
【解决方案2】:

这很简单 您还没有重新实现方法 public void setNext() 没有参数!

如果您需要它不要抱怨,请更改您的界面以像这样声明setNext

public void setNext(BasicListNode<T> node);

或像声明的那样实现接口;-)

【讨论】:

    【解决方案3】:

    在您的界面中:

    public void setNext();
    

    在你的课堂上:

    public void setNext(BasicListNode<T> node)
    

    【讨论】:

      【解决方案4】:

      这里的问题是你需要实现方法:

      public void setNext(IBasicListNode<T> node);
      

      注意参数node 的类型实际上是IBasicListNode&lt;T&gt; 而不仅仅是BasicListNode&lt;T&gt;

      看看ArrayList的实现方式(here)。它实现了Collection 接口。然而没有addAll(ArrayList&lt;T&gt; list) 方法。相反,它必须实现Collection 接口,因此它必须实现addAll(Collection&lt;? extends E&gt; c) 方法。

      在您的示例中,您希望将界面更改为如下所示:

      public void setNext(IBasicListNode<T> node);
      

      然后在你的BasicListNode类中实现方法如下:

      public void setNext(IBasicListNode<T> node) {
          this._next = node;
      }
      

      *注意:您的_next 变量现在必须是IBasicListNode&lt;T&gt; 类型,或者您必须通过某种方式检查并转换为BasicListNode

      编辑: 需要明确的是,ArrayList 实际上可以包含一个名为 addAll(ArrayList&lt;T&gt; list) 的方法,如果它愿意,但这是可选的。但是,它绝对必须包含一个名为addAll(Collection&lt;? extends E&gt; c) 的方法才能完全实现Collection 接口。

      故事的要点是,在实现接口时,您的类必须包含与其正在实现的接口相同的方法签名。即必须具有相同的返回类型、相同的方法名和参数列表必须具有相同的类型和顺序。

      编辑 2: 要将instanceof 与泛型一起使用,您需要使用通配符&lt;?&gt;,如下所示:

      if(node instanceof BasicListNode<?>) {
          this._next = (BasicListNode<T>)node;
      }
      

      这是必需的,因为&lt;T&gt; 不是可以在编译时检查的类型,因为您不知道在运行时将使用哪种类型。 &lt;?&gt; 允许您接受任何泛型类型的 BasicListNode

      至于为什么getNext() 方法在返回类型略有不同的情况下仍然有效,这与泛型的力量有关。使用泛型时有很多特殊情况,需要多一点时间才能理解。有关更多详细信息,我建议您查看泛型,也许看看这篇文章here。接受的答案只会让事情变得更加混乱,所以我建议看看 Cam 提供的第二个答案

      【讨论】:

      • 感谢您的精彩解释。但是您能否详细说明? extends E 是如何使用的?
      • @jiewmeng &lt;? extends E&gt; 用于允许泛型类型是 E 的子类的任何对象。例如,考虑一个名为 draw(ArrayList&lt;? extends Shape&gt; shape) 的方法,该方法绘制任何扩展 @ 987654352@上课。使用&lt;? extends Shape&gt; 通配符,您可以将包含CircleRectangle 或任何其他形状的ArrayList 传递给它,只要它扩展Shape 类即可。
      • 我想知道,如果我的函数只需要使用@987654359 中定义的方法,我的班级坚持允许IBasicListNode&lt;T&gt; 而不是说期望BasicListNode&lt;T&gt;(用于参数)是否更好@?那么退货呢?我是否应该始终返回更具体的类型,以便有空间将其转换为更通用的类型?
      • 如果我的方法签名显示我需要一个IBasicListNode 并抛出一个异常说我需要一个BasicListNode,这看起来很混乱。我发现如果我在实现中使用 IBasicListNode,如果我需要 BasicListNode 中的功能,我会遇到问题/困惑
      【解决方案5】:

      你的界面有以下方法:

      public void setNext(IBasicListNode<T> node);
      

      但是你的班级有这个:

      public void setNext(BasicListNode<T> node) {
      

      因此不遵守约定:接口方法接受IBasicListNode&lt;T&gt; 的任何实现作为参数,而类方法只接受特定的BasicListNode&lt;T&gt; 实现。

      【讨论】:

        猜你喜欢
        • 2012-08-12
        • 1970-01-01
        • 2023-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-14
        相关资源
        最近更新 更多