Java complains I haven't implemented a method
I have the following interface:
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);
}
And a class:
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;
}
}
And I got the folloeing error:
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 BasicListNo开发者_StackOverflowde<T> implements IBasicListNode<T> {
^
Why isn't java detecting that BasicListNode<T> implements IBasicListNode<T>
?
The problem here is that you need to implement the method:
public void setNext(IBasicListNode<T> node);
Note the type of the parameter node
is in fact IBasicListNode<T>
and not simply BasicListNode<T>
.
Take a look at the way ArrayList
is implemented (here). It implements the Collection
interface. Yet there is no addAll(ArrayList<T> list)
method. Instead it must implement the Collection
interface and thus it must implement a addAll(Collection<? extends E> c)
method.
In you example you want to change your interface to read as follows:
public void setNext(IBasicListNode<T> node);
Then implement the method in your BasicListNode
class as follows:
public void setNext(IBasicListNode<T> node) {
this._next = node;
}
*Note: Your _next
variable must now be of type IBasicListNode<T>
or you must some how check for and cast to BasicListNode
.
EDIT:
To be clear ArrayList
could in fact contain a method called addAll(ArrayList<T> list)
if it wanted to but that is optional. However, it absolutely must contain a method called addAll(Collection<? extends E> c)
in order to fully implement the Collection
interface.
The take away of the story is that when implementing an interface your class must contain a method signature that is identical to the interface it is implementing. That is it must have the same return type, the same method name and the parameter list must have the same types and order.
EDIT 2:
To use instanceof
with generics you will need to use the wildcard <?>
as follows:
if(node instanceof BasicListNode<?>) {
this._next = (BasicListNode<T>)node;
}
This is needed as <T>
is not a type that can be checked against at compile time since you don't know what type will be used at runtime. The <?>
allows you accept a BasicListNode
of any type generic.
As to why the getNext()
method works despite having a slightly different return type has to do with the power of generics. There are a lot of special cases when using generics and requires a little more time to understand it all. For more details I would recommend looking up generics and perhaps taking a look at this post here. The accepted answer will only make things a little more confusing so I recommend taking a look at the second answer provided by Cam
your setnext()
in the interface class should be
public void setNext(BasicListNode<T> node);
Its missing the argument that's implemented in the class. Change the interface to match the class or the class to match the interface and it will stop complaining.
Your interface should be:
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);
}
For your next error remember to put
public
infront of
public class BasicListNode<t> implements BasicListNodeI<T>
and
public interface IBasicListNode<T>
In your interface:
public void setNext();
in your class:
public void setNext(BasicListNode<T> node)
It's simply
You haven't reimplemented method public void setNext()
without arguments!
If you need it to don't complain, change your interface to declare setNext
like this
public void setNext(BasicListNode<T> node);
or implement interface like it is declared ;-)
Your interface has the following method:
public void setNext(IBasicListNode<T> node);
But your class has this one:
public void setNext(BasicListNode<T> node) {
The contract is thus not respected: the interface method accepts any implementation of IBasicListNode<T>
as argument, whereas the class method only accepts the specific BasicListNode<T>
implementation.
精彩评论