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 LabOnInterfacesPart1.mcp.
- 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 looking 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!