|
CS 334
|
Here is an example:
class A
feature
x: C;
m() is
do
x = C.create()
end
end
class B inherit A
feature
x: D;
n() is
do
x.methodOfDonly()
end
end
b: B;
b = B.create();
b.m();
b.n();
This program crashes after b.n() because after b.m(), x holds a value of C
and n sends method of D only to x -- crash!
class LINKABLE [G]
feature
item: G; -- value held
right: like Current; -- Right neighbor
putRight (other: like Current) is
-- Put `other' to the right of current cell.
do
right := other
ensure
chained: right = other
end;
end -- class LINKABLE
class BILINKABLE [G] inherit
LINKABLE [G]
redefine
putRight
end
feature -- Access
left: like Current; -- Left neighbor
putRight (other: like Current) is
-- Put `other' to the right of current cell.
do
right := other;
if (other /= Void) then
other.simplePutLeft (Current)
end
end;
putLeft (other: like Current) is
-- Put `other' to the left of current cell.
do
left := other;
if (other /= Void) then
other.simplePutRight (Current)
end
ensure
chained: left = other
end;
feature {BILINKABLE}
simplePutRight (other: like Current) is
-- set `right' to `other'
do
right := other
end;
simplePutLeft (other: like Current) is
-- set `left' to `other'
do
left := other
end;
invariant
rightSymmetry:
(right /= Void) implies (right.left = Current);
leftSymmetry:
(left /= Void) implies (left.right = Current)
end -- class BILINKABLE
While there are no type errors in the definition of BILINKABLE, please
write some code which shows that BILINKABLE is not a subtype of LINKABLE.
That is, write a method or procedure which takes a parameter of type
LINKABLE (and perhaps others) and which is type-correct when a value of
type LINKABLE is passed in, yet which crashes if an object of type
BILINKABLE is passed in.
breakit(fst: LINKABLE[STRING], snd: LINKABLE[STRING]) is
do
fst.setNext(snd);
end;
Calling breakit(blnode,lnode) with blnode: BILINKABLE and lnode: LINKABLE
will cause a crash because setNext of BILINKABLE sends a message
simplePutLeft to its argument. That argument is a LINKABLE and hence does
not understand the message.
// Interface for node objects w/ values of type String
public interface NodeIfc<T>{
// Returns following node.
T getNext();
// Hook up newNext to the right of this
void setNext(T newNext);
// Returns value stored in node
String getValue();
// Sets value stored in node to newVal
void setValue(String newVal);
}
-----------------------------------------
// Interface for doubly-linked node objects w/ values of type String
public interface DbleNodeIfc<T> extends NodeIfc<T>{
// Returns preceding node.
T getPrevious();
// Set node bfore this to be newPrevious
void setPrevious(T newPrevious);
}
-----------------------------------------
// Interface for Ordered List of Strings, parameterized by the type of node.
// Note use of F-bounded polymorphism.
import java.util.Enumeration;
public interface OrdListIfc< N implements NodeIfc<N>>{
// Return true iff val is in list
boolean inList(String val);
// Add newNode to list (in proper order). Duplicates are OK.
void add(N newNode);
// Return an Enumeration which will go through all elements of list in order.
Enumeration getEnumerator();
// If val is in list, delete first copy and return true, else return false.
boolean delete(String val);
}
Please write GJ classes:
The class OrdList should result in a singly linked list if it is
instantiated with SNode, and a doubly-linked list if instantiated
with DNode.
// Return Enumeration which goes through elements of list in reverse order. public Enumeration getRevEnumerator();
You will also have to override methods add and delete to ensure that the tail instance variable gets overridden properly. See if you can write them so that you call the inherited method from the superclass and then simply execute a few extra instructions to make sure that tail has the proper value.
Code not included
Code not included.