在Java中实现接口

时间:2011-03-30 15:03:28

标签: java interface

我编写了一个实现Queue接口的框架类。当我编译时,我得到一个ErrMsg要求从Object类实现add方法(或者它是否引用了Object接口?我在Java API中查找了它们,并且它们都没有添加方法)

为什么我会收到此错误,是否意味着实现给定接口的非抽象类需要实现实现类中的所有方法?我原以为不会。

import java.util.* ;
class  ArrayQueue implements Queue
{
    private Object[] elems ;
    private int front, rear, length ;

    public static void main(String[] args) 
    {
        System.out.println("Hello World!");
    }

    public ArrayQueue(int maxLength)
    {
        length = 0 ;
        front = 0 ;
        rear = 0 ;
        elems = new Object[maxLength] ;
    }

    public  boolean offer(Object o) {}

    public  Object poll() {}

    public  Object remove() {}

    public  Object peek() {}

    public  Object element() {}
}

编译器消息:

  

ArrayQueue不是抽象的   不要覆盖抽象方法   add(java.lang.Object)in   java.util.Queue中

顺便说一下,除了家庭作业之外还有其他标签可以说这是在学习的背景下完成的吗?这不是我正在做的功课,但它与我所做的一样接近:学习......

[编辑]

我一直在看这个API页面,它没有提到add()...我在看错了页面吗?

http://download.oracle.com/javase/1.5.0/docs/api/

9 个答案:

答案 0 :(得分:3)

实现接口的类必须实现接口中方法的全部,以及接口继承的任何其他接口中的所有方法。

abstract类不需要实现它实现的接口中的所有方法,但是任何继承抽象类的具体类都可以。

接口的全部意义在于,任何实现接口的类都可以透明地用作实现 如果类不需要实现其所有接口的成员,那将失败目的。

在您的示例中,如果有人写

会发生什么
Collection myQueue = new ArrayQueue();
myQueue.add("Hi!");

此代码调用您未编写的方法。


错误告诉您,您没有实现一个名为add的方法,其中 Object作为参数。
该方法来自Queue接口,正如它在消息末尾所说的那样 Queue接口依次从Collection接口继承此方法。

答案 1 :(得分:2)

错误消息是关于Queue界面本身的add() method。另请注意,Queue扩展了CollectionIterable,因此您还需要实现这些接口的方法。

另一种方法是让您的班级延长AbstractQueue - 这可以为您节省大量工作。

答案 2 :(得分:1)

实现接口的类必须实现接口的所有方法,除非它是一个抽象类。这就是错误的含义。

要修复它,您需要实现add()方法或使类抽象。

您缺少this方法。

答案 3 :(得分:1)

如果您查看界面java.util.Queue,您会看到有一个方法,add()只需一个参数,java.lang.Object

为了实现Queue接口,您需要实现该方法。

更一般地说,每当你implement一个类中的接口时,你需要在该接口中编写每个方法的实现(或者将你的类标记为abstract)。

请注意,编译器并没有要求您从java.lang.Object实现方法,它要求您实现签名add(java.lang.Object)的接口,这意味着一种方法使用add类型的单个参数命名java.lang.Object

答案 4 :(得分:1)

此错误消息表明您尚未使用以下原型实现该方法:

add(java.lang.Object)

(因此,提到的Object类被称为参数类型)并且在Queue接口中声明。

答案 5 :(得分:0)

java.util.Queue 确实拥有add方法,因此如果您延长Queue,则必须实施此方法。

消息提到Object的原因是因为Queue API指定add方法采用Object类型的参数。

答案 6 :(得分:0)

由于Queue扩展了Collection,您需要使用public boolean add(Object o)方法。

它不是要求Object的方法,只是要求一个将对象作为参数的方法。

以下是您还需要实施的内容:

 boolean    add(E o)
 boolean    addAll(Collection<? extends E> c)
 void   clear()
 boolean    contains(Object o)
 boolean    containsAll(Collection<?> c)
 boolean    equals(Object o)
 int    hashCode()
 boolean    isEmpty()
 Iterator<E>    iterator()
 boolean    remove(Object o)
 boolean    removeAll(Collection<?> c)
 boolean    retainAll(Collection<?> c)
 int    size()
 Object[]   toArray()
<T> T[]

答案 7 :(得分:0)

boolean add(E e)Queue接口的一种方法。您必须实现它才能拥有一个功能完备的队列。

答案 8 :(得分:0)

实现接口的类不仅必须实现接口中的所有方法 - 它还必须满足接口的整个行为契约。这是因为 Liskov替换原则表明,根据其接口中指定的记录行为,类的任何子类(或接口的实现)必须可用于代替超类。该语言需要考虑到必须拥有所有类方法的事实,但是如果你看一下Queue.add(E)的规范,我们就有:

  

如果可以立即执行此操作而不违反容量限制,则将指定的元素插入此队列,成功时返回true,如果当前没有可用空间则抛出IllegalStateException

     

指定者:   界面add

中的Collection<E>      

<强>参数:   e - 要添加的元素

     

<强>返回:   true(由Collection.add(E)指定)

     

<强>抛出:   IllegalStateException - 如果由于容量限制而无法在此时添加元素;   ClassCastException - 如果指定元素的类阻止将其添加到此队列中;   NullPointerException - 如果指定的元素为null并且此队列不允许null元素;   IllegalArgumentException - 如果此元素的某些属性阻止将其添加到此队列

您的实施必须执行此处指定的所有操作。覆盖方法看似简单,但通常很难做到正确,所以正如其他人所建议的那样,通常最好通过子类化AbstractQueue之类的部分实现来尽量减少覆盖的次数。