overriding object.clone() problem

J

Jason Evans

Hi All,

I am writing my own implementation of queue via a linked list, note
not a LinkedList, and was running into trouble with the clone method.
I was wondering if anyone could point out some not so obvious errors I
have made..

Cheers


public class QueueLinkedList implements Queue {


private QueueNode front; // note that ONLY front is used
private QueueNode rear; // for empty tests
private int numItems;

/* *******************************************************************
*/
/** create a queue
*
*/
public QueueLinkedList() {
front = null;
numItems = 0;
} // constructor QueueLinkedList

/** create a queue which can hold up to size elements
*
* @param max the size of the Queue to be created
* ie the maximum number elements it can hold
*/
public QueueLinkedList(int max) {
this(); // ignore max!
} // constructor QueueLinkedList

/* *******************************************************************
*/
/** Returns a string representation of the Queue <br> <br>
* pre: <br>
* post: a comma separated list of elements is returned starting
at front
*
* @return a string representation of the Queue consisting of a
comma
* element list starting with the element at the front of
the
* Queue
*/
public String toString() {
String s = "";
QueueNode node = front;

if (node != null) { // all except first has leading comma & no
(front)
s = "(FRONT) " + node.item;
node = node.link;
}
while (node != null) {
s = s + ", " + node.item;
node = node.link;
}
return s;
} // toString

/* *******************************************************************
*/
/** Removes all elements from this Queue <br> <br>
* this : [ TRUE, this = < > ]
*/
public void makeEmpty( ) {
front = null;
numItems = 0;
} // makeEmpty

/* *******************************************************************
*/
/** Determines whether this Queue is empty. <br> <br>
* : [TRUE, result = ( this = < > ) ]
*
* @return the boolean value 'this Queue is empty'
*/
public boolean isEmpty() {
return numItems==0;
// or return front==null or rear==null;
}

/* *******************************************************************
*/
/** Determines whether this Queue is full. <br> <br>
* : [ TRUE , result = ( #this = max) ]
*
* @return the boolean value 'this Queue is full'
*/
public boolean isFull() {
return false;
} // isFull

/* *******************************************************************
*/
/** Determines number of elements in this Queue. <br> <br>
* : [ TRUE , result = #this ]
*
* @return the number of elements in this Queue
*/
public int size() {
return numItems;
}

/* *******************************************************************
*/

/** Adds "element" to this Queue <br> <br>
* this : [ #this<max, fr this = this0 AND lt this = element]
*
* @param element the element to be added at the end of this
Queue.
*/
public void insert(Element item) {
QueueNode node = new QueueNode();

// if queue was empty, new node is also front
if (front == null) {
front = node;

// else add new node at rear
} else {
rear = node;
}
node.link = null; // not needed

// either way, it's the new rear
rear = node; // ???

// another logical step
node.item = item.copy();

// and another
numItems++;
}

/* *******************************************************************
*/
/** Removes and returns the element at the front of this Queue
<br> <br>
* this : [ #this > 0, tl this0 = this AND result = hd this0]
*
* @return the element which has been removed from the front of
this
* (previously) non-empty Queue.
*/
public Element remove(){
QueueNode node;

// remove the front
node = front;
front = null;

numItems--;

// if this made the queue empty, update rear too
node = rear.link
rear.link = node.link;
}

return rear.link;
}

/* ******************************************************************
*/
/** Returns the element at the front of this Queue without
removing it
* <br> <br>
* : [ #this > 0, result = hd this0]
*
* @return the element located at the front of this non-empty
Queue.
*/
public Element front( ) {
return rear.link.item.copy();
}

/* ******************************************************************
*/
/** Applies the "visit" method of "forAllObj" to all the elements
of this
* Queue <br> <br>
* this : [ TRUE, this = Vs:this0 . forAllObj.visit(s) ]
*/
public void forAll(ForAll forAllObj) {

if (front!=null) {
QueueNode node=front;
do {
forAllObj.visit(node.item);
node=node.link;
} while (node!=null);
}

} // forAll

/**
* Creates a new Queue having the same elements as this Queue.
<br>
* N.B. A new Queue is created, not just another reference to this
* Queue.<br>
* Overrides the protected Object.clone() method, so that
references
* outside the Object-SD2Set hierarchy can be used to call clone()
* public Object clone(). <p>
* , :[true, result=this] <br>
* pre: True. <br>
* post: A deep copy of this Queue is returned.
*
* @return A deep copy of this Queue.
*/
public Object clone() {
try {
QueueLinkedList clone = (QueueLinkedList)super.clone();

// clone the first node, if any
if (front!=null) {
clone.front = new QueueNode();
clone.front.item = (Element)front.item.clone();

// clone the rest of the queue contents, if any
QueueNode current = front.link;
QueueNode clonePrevious = clone.front;
while (current != null) {
clonePrevious.link = current.link;
clonePrevious = current;
clonePrevious.item = front.item;
current = front;
}
// XXXXXX
}

return clone;
} catch (CloneNotSupportedException cNSE) {
throw new Error("This can't happen");
}
}

}

class QueueNode

{

Element item;
QueueNode link;

/**
* Construct an empty QueueNode object
*/
public QueueNode() {
} // QueueNode

}

The Queue interface just says methods such as remove and insert must
be implemented, it also says public Object clone(); must be
implemented, which overides Object.clone()

The errors I get are:

QueueSD2LinkedList.java:2: The method java.lang.Object clone()
declared in class java.lang.Object cannot override the methode
signature declared in interface Queue. The access modifier is made
more restrictive.

also:

The method java.lang.Object clone() declared in class java.lang.Object
cannot override the method of the same signature declared in interface
Queue. Their throws clauses are incompatible.

Any light shed on this would be most helpfull
 
Y

Yu SONG

Jason said:
Hi All,

I am writing my own implementation of queue via a linked list, note
not a LinkedList, and was running into trouble with the clone method.
I was wondering if anyone could point out some not so obvious errors I
have made..

Cheers


public class QueueLinkedList implements Queue {


private QueueNode front; // note that ONLY front is used
private QueueNode rear; // for empty tests
private int numItems;

/* *******************************************************************
*/
/** create a queue
*
*/
public QueueLinkedList() {
front = null;
numItems = 0;
} // constructor QueueLinkedList

/** create a queue which can hold up to size elements
*
* @param max the size of the Queue to be created
* ie the maximum number elements it can hold
*/
public QueueLinkedList(int max) {
this(); // ignore max!
} // constructor QueueLinkedList

/* *******************************************************************
*/
/** Returns a string representation of the Queue <br> <br>
* pre: <br>
* post: a comma separated list of elements is returned starting
at front
*
* @return a string representation of the Queue consisting of a
comma
* element list starting with the element at the front of
the
* Queue
*/
public String toString() {
String s = "";
QueueNode node = front;

if (node != null) { // all except first has leading comma & no
(front)
s = "(FRONT) " + node.item;
node = node.link;
}
while (node != null) {
s = s + ", " + node.item;
node = node.link;
}
return s;
} // toString

/* *******************************************************************
*/
/** Removes all elements from this Queue <br> <br>
* this : [ TRUE, this = < > ]
*/
public void makeEmpty( ) {
front = null;
numItems = 0;
} // makeEmpty

/* *******************************************************************
*/
/** Determines whether this Queue is empty. <br> <br>
* : [TRUE, result = ( this = < > ) ]
*
* @return the boolean value 'this Queue is empty'
*/
public boolean isEmpty() {
return numItems==0;
// or return front==null or rear==null;
}

/* *******************************************************************
*/
/** Determines whether this Queue is full. <br> <br>
* : [ TRUE , result = ( #this = max) ]
*
* @return the boolean value 'this Queue is full'
*/
public boolean isFull() {
return false;
} // isFull

/* *******************************************************************
*/
/** Determines number of elements in this Queue. <br> <br>
* : [ TRUE , result = #this ]
*
* @return the number of elements in this Queue
*/
public int size() {
return numItems;
}

/* *******************************************************************
*/

/** Adds "element" to this Queue <br> <br>
* this : [ #this<max, fr this = this0 AND lt this = element]
*
* @param element the element to be added at the end of this
Queue.
*/
public void insert(Element item) {
QueueNode node = new QueueNode();

// if queue was empty, new node is also front
if (front == null) {
front = node;

// else add new node at rear
} else {
rear = node;
}
node.link = null; // not needed

// either way, it's the new rear
rear = node; // ???

// another logical step
node.item = item.copy();

// and another
numItems++;
}

/* *******************************************************************
*/
/** Removes and returns the element at the front of this Queue
<br> <br>
* this : [ #this > 0, tl this0 = this AND result = hd this0]
*
* @return the element which has been removed from the front of
this
* (previously) non-empty Queue.
*/
public Element remove(){
QueueNode node;

// remove the front
node = front;
front = null;

numItems--;

// if this made the queue empty, update rear too
node = rear.link
rear.link = node.link;
}

return rear.link;
}

/* ******************************************************************
*/
/** Returns the element at the front of this Queue without
removing it
* <br> <br>
* : [ #this > 0, result = hd this0]
*
* @return the element located at the front of this non-empty
Queue.
*/
public Element front( ) {
return rear.link.item.copy();
}

/* ******************************************************************
*/
/** Applies the "visit" method of "forAllObj" to all the elements
of this
* Queue <br> <br>
* this : [ TRUE, this = Vs:this0 . forAllObj.visit(s) ]
*/
public void forAll(ForAll forAllObj) {

if (front!=null) {
QueueNode node=front;
do {
forAllObj.visit(node.item);
node=node.link;
} while (node!=null);
}

} // forAll

/**
* Creates a new Queue having the same elements as this Queue.
<br>
* N.B. A new Queue is created, not just another reference to this
* Queue.<br>
* Overrides the protected Object.clone() method, so that
references
* outside the Object-SD2Set hierarchy can be used to call clone()
* public Object clone(). <p>
* , :[true, result=this] <br>
* pre: True. <br>
* post: A deep copy of this Queue is returned.
*
* @return A deep copy of this Queue.
*/
public Object clone() {
try {
QueueLinkedList clone = (QueueLinkedList)super.clone();

// clone the first node, if any
if (front!=null) {
clone.front = new QueueNode();
clone.front.item = (Element)front.item.clone();

// clone the rest of the queue contents, if any
QueueNode current = front.link;
QueueNode clonePrevious = clone.front;
while (current != null) {
clonePrevious.link = current.link;
clonePrevious = current;
clonePrevious.item = front.item;
current = front;
}
// XXXXXX
}

return clone;
} catch (CloneNotSupportedException cNSE) {
throw new Error("This can't happen");
}
}

}

class QueueNode

{

Element item;
QueueNode link;

/**
* Construct an empty QueueNode object
*/
public QueueNode() {
} // QueueNode

}

The Queue interface just says methods such as remove and insert must
be implemented, it also says public Object clone(); must be
implemented, which overides Object.clone()

The errors I get are:

QueueSD2LinkedList.java:2: The method java.lang.Object clone()
declared in class java.lang.Object cannot override the methode
signature declared in interface Queue. The access modifier is made
more restrictive.

also:

The method java.lang.Object clone() declared in class java.lang.Object
cannot override the method of the same signature declared in interface
Queue. Their throws clauses are incompatible.

Any light shed on this would be most helpfull


You posted the wrong code...

There is something wrong the Queue interface (Where is the
"QueueSD2LinkedList.java"?)


You can find the answer here
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#clone()
 
M

Michael Borgwardt

Yu said:
You posted the wrong code...

And you needed to quote the entire TWO-HUNDRED-AND-FUCKING-FIFTY lines
to tell him that???
There is something wrong the Queue interface (Where is the
"QueueSD2LinkedList.java"?)

No. What's wrong is that the interface contains the clone() method,
and as an interface method it is public. Therefore it can't be
implemented by the clone() inherited from Object, which is protected.
He needs to override it (forwarding to the superclass method) and
also implement the Cloneable interface.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top