Lab on Interfaces
Disclaimer: This
lab is pretty dense. If you donŐt finish it in the lab time please finish it at
home before attempting homework. Lab description is very detailed so you should
be able to complete it on your own, whereas it is necessary for understanding
the homework assignment!!
In this lab you will learn
to deal with interfaces which will prove very helpful for the next Homework.
You will see the beauty of lists working with a standardized interface, which
would enable you to reuse the list structure to create lists of whatever you
want and still have all the standard methods of the list working properly.
You will start out by defining a new method for lists. You will have to take into account the
fact that your lists are now able to work with any class that implements an
interface Thing. You will then define an interface and overload necessary
methods for classes that implement this interface.
Next step would require you to learn to use a standard
interface Comparable and implement its method called int compareTo(Object o). Then test it on a couple of classes.
By the end of the lab you should be comfortable enough with
interfaces to do your Homework and use them every so often.
WARNING: This project will not compile until you make the
changes outlined below!
- Open the project
LabOnInterfaces.
- Notice that you have ACollectionList, ConsCollection
and EmptyCollection
defined for you.
- Check what this is a list of (look at the type of the
Member Data first in ConsCollection). This is a list of Things.
- What is a Thing?
It is an interface. So
we will be manipulating any class that will implement this interface Thing.
- Now look at the ConsCollection. It mentions a method Thing most_valuable() that
you are going to define in this lab. What does this method return? Do we pass any arguments? It returns a Thing and it is called
by a list so it has all the data available to it, so it has no
arguments. Think how you keep look for most
valuable thing in the list if you can look at it only one item at a
time. You need to keep
traversing the list while keeping track of the most_valuable_so_far that
can be compared to each item in the list. If you find something better along the way, then it
becomes your most_valuable_so_far. To implement this idea we will
need to develop a helper method
Thing most_valuable_helper (Thing
most_valuable_so_far).
- The
method Thing most_valuable_helper (Thing
most_valuable_so_far) is called on a list; if first Thing is
less than most_valuable_so_far,
then we just proceed by calling this method on the rest of the list and keep
the same most_valuable_so_far. Otherwise we call it on the rest of
the list but pass the first instead
of most_valuable_so_far. Write the body of this method in ConsCollection using >,
< = for comparison of Things.
- Now what happens if we hit an empty list? This means we reached the end of
the list, so we should return what we found to be most_valuable_so_far. Write the body of most_valuable_helper in
EmptyCollection.
- Now back to most_valuable(). How do we call most_valuable_helper()
from most_valuable()? Basically we just need to
initialize the most_valuable_so_far
and pass it to the method.
Since we are just starting, the most_valuable_so_far is
Thing first and then we proceed to call most_valuable_helper(first)
on the rest of the list. What
does most_valuable() return? It returns whatever most_valuable_helper(first)
gives back to it. Write
the body of this method in ConsCollection.
- What if most_valuable() was
called from the EmptyCollection? Well, how can we find anything in
an empty list? We donŐt even
declare it there, so if the call ever occurs an error will be raised by
the program, telling that whoever made this call is just plain silly!
- Now lets get back to the body of most_valuable_helper() in ConsCollection. Did you really believe me when I
told you to use >, < = to compare two Things? Do you know how to do it
correctly? Clueless, huh! Then refer to the Thing interface (Thing.java). What does it tell you? It tells you that whatever the
thing is, it will have a method int compare_value (Object other_thing). This method returns 1 if this > other_thing,
0 if this =
other_thing, -1 otherwise. Hm, looks like something we could use! Modify most_valuable_helper() accordingly,
so now it uses compare_value() to
compare two Things.
- Now look at the insert() method. It also
uses > to compare things. Modify it so that it operates depending on the output
of compare_value().
- Now we are ready to get to testing. LetŐs create a collection of Lions. What the hell, Lion is not a Thing! Not yet, but once you
write implements Thing (where
you would usually write extends blah-blah-blah) it now implements the Thing interface.
- Is that it?
Yeah, you wish. Now we
have to implement
all the methods mentioned in the Thing. Luckily it is only compare_value(Object
other_thing).
When is Lion more valuable? When it is fat! Then compare_value() will
compare Lions
by weight. Look at the code, see how there is
an integer output corresponding to every case, just as you expected.
- Now whatŐs up with the weird syntax ((Lion) other_thing).weight? It is called type casting. Notice
that other_thing
is an Object. But we know that this method
compares Lion
to a Lion and not to a random Object. Unfortunately, we canŐt change the
definition in the interface since it is a template to all classes that
implement it, which is not necessarily Lion. So we remind the method that Ňhey,
you are dealing with a LionÓ,
treat this Object
as a member of a class Lion,
which is what writing (Lion)other_thing
does.
- Now uncomment the
test for a collection of Lions (LionCage1,
LionCage2) in the ACollectionListTest.java. Compile, check if the output makes
sense.
- What if we wanted a collection of paintings? What changes do we have to make to
Painting class? Write ..implements Thing. Implement a method int
compare_value(Object other_thing) similarly to that of Lion,
except now we are comparing $ values of paintings, which is expressed by price. When done defining, uncomment the
test for a collection of Painting in the ACollectionListTest.java. Compile,
run.
- Now since all of the above Ňmade senseÓ you can learn
to use interface Comparable. It is a standard interface that
guess what.....is provided for you by java library so you donŐt have to
define it.
- Open project LabOnInterfacesPart2.mcp. Looks the same, except we did away
with Thing,
since we are not going to use it anymore. Check what do we have a list of. Now it is Comparable. But would our methods designed for
Thing work if we just change every instance of Thing to Comparable? NO!!!!!!!!!! Why? Look at the most_valuable(), what was so special about
the Thing? It was the compare_value()
method. Now we need to look
for something of that sort in the Comparable interface, hopefully you wonŐt
have to change your method around too much to work with Comparables. Well, guess what! Comparable has int compareTo(Object o)
that acts just like compare_value(Object
other_thing).
Coincidence? I donŐt
think so...
- Now just go
to two places that used compare_value() and change it to compareTo(). What would be the next step?
- Go to classes we are using to test a list on and change
everything from Thing to Comparable. Hard? I hope not, it is just 2 changes, considering that even
for compareTo(Object o) method
you can use the body of what used to be compare_value(Object other_thing). DonŐt forget to change variable
names though.
- Compile, Run,
every test should work fine.
- So, kids, what did we learn?
That we can create lists
of interfaces and define methods on it without even knowing what classes we are
dealing with. The only thing we
need to do is to make sure that these classes have some necessary methods
implemented (the ones mentioned in the interface).
Another nice
thing is that for simple use of classes we donŐt even need to define an
interface but use an existing one, like Comparable. Cool, less work is gooooood! So we can say implements Comparable and
there is only one thing: donŐt forget to implement int compareTo(Object o),
well it will give you an error if you donŐt. When you write your own int compareTo(Object o) what
should you remember? That you will
need to cast your current class type on this Object o just like (Lion) other_thing.
- Since it is all so awesome and we just might have a
couple of minutes before the quiz, we should create another class that implements Comparable and test it in
a list. Lets call it FunnyString
and it has a regular String member_string as its data member. FunnyStrings
are compared by length. So in
int
compareTo(Object other_FunnyString) would
compare its member_string.length()
to other_FunnyString.member_string.length(). Oh yeah, donŐt forget to remind
the method that other_FunnyString
is a FunnyString...TYPE
CAST! When done with
definition, uncomment the test for FunnyString in ACollectionListTest. Compile, Run. Sweeeeeeeeeeet!
- Now get paper and pen and prepare for the quiz.