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!

 

  1. Open the project LabOnInterfacesPart1.mcp.
  2. Notice that you have ACollectionList, ConsCollection and EmptyCollection defined for you.
  3. Check what this is a list of (look at the type of the Member Data first in ConsCollection).  This is a list of Things.
  4. What is a Thing?  It is an interface.  So we will be manipulating any class that will implement this interface Thing.
  5. 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). 

  1. 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.
  2. 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.
  3. 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.
  4. 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!
  5. 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.
  6. 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().
  7. 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.
  8. 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.
  9. 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.
  10. Now uncomment the test for a collection of  Lions (LionCage1, LionCage2) in the ACollectionListTest.java.  Compile, check if the output makes sense.
  11. 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.
  12. 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.
  13. 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...
  14. Now just go to two places that used compare_value() and change it to compareTo().  What would be the next step?
  15. 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.
  16. Compile, Run, every test should work fine.
  17. 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.

  1. 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!