我编写了一个实现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()...我在看错了页面吗?
答案 0 :(得分:3)
实现接口的类必须实现接口中方法的全部,以及接口继承的任何其他接口中的所有方法。
abstract
类不需要实现它实现的接口中的所有方法,但是任何继承抽象类的具体类都可以。
接口的全部意义在于,任何实现接口的类都可以透明地用作实现 如果类不需要实现其所有接口的成员,那将失败目的。
在您的示例中,如果有人写
会发生什么Collection myQueue = new ArrayQueue();
myQueue.add("Hi!");
此代码调用您未编写的方法。
错误告诉您,您没有实现一个名为add
的方法,其中将 Object
作为参数。
该方法来自Queue
接口,正如它在消息末尾所说的那样
Queue
接口依次从Collection
接口继承此方法。
答案 1 :(得分:2)
错误消息是关于Queue
界面本身的add() method。另请注意,Queue
扩展了Collection
和Iterable
,因此您还需要实现这些接口的方法。
另一种方法是让您的班级延长AbstractQueue
- 这可以为您节省大量工作。
答案 2 :(得分:1)
答案 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
之类的部分实现来尽量减少覆盖的次数。