CM10135 / Programming II:   Lecture 7


Space, Class & Interfaces



-I. The Big Picture

  1. First half of this section of this course is on general principles.
    1. Algorithms
    2. Sorting
    3. Complexity
    4. Searching
  2. Second half is too to some extent, but more emphasis back on Java.
    1. Concurrency & Threading
    2. GUIs
    3. Internet Programming
  3. This lecture is the transition between halves. 
    1. Will get back to some searching in my last week of lectures.
    2. This lecture addresses things you should already know from Programming I, but may not have quite gotten.
    3. It will help with your first coursework.
  4. The main theme of this lecture is visualizing memory --- understanding where it is.
    1. Everything has to be in memory somewhere --- including the program itself!

I. Trees, Logs & Exponentiation: a last exercise in complexity

  1. In 2005 when I talked about AI in week 6, only one person in the class saw that the tree was growing exponentially.
    1. By the rule of parallel search, someone in a class should have come up with almost everything!
    2. Someone also said "factorial."
    3. You guys should try to do better!
  2. Trees are a good way to think about both exponentiation & about logarithms.
  3. b = branching factor, d = depth of tree, N = number of elements.
                      o				b0 nodes in level 0
    / \
    o o b1 nodes in level 1
    / \ / \
    o o o o b2 nodes in level 2
    / \ / \ / \ / \
    o oo oo oo o b3 nodes in level 3
    In general, N= bd + bd-1 + ... b0
    1. As we know, this is dominated by the largest term, bd (see lecture 4). 
      1. Things would be different if we were multiplying, not adding.
      2. Factorial is when you multiply 1 * 2 * 3 * ... N
    2. So N grows exponentially on the depth of the tree,
      1. the base of the exponent is the branching factor of the tree.
    3. On the other hand, a length of the path from the root to the leaves of the tree is logarithmic on N,
      1. the branching factor is the base of the log too.
    4. N = O(bd), d = O(logb(N)).  In the case above, b =2, 8 = 23, 3 = log2(8).

II. Static Memory and Class Variables

  1. What are class variables & where do they get stored?
    1. Why do you declare them with the word static?
  2. We will start out thinking about languages in general, then look at howearly languages like C have impacted Java.
    1. History affects everything, even programming.
    2. The basic problems don't change, although our approaches to solving them do a bit.
  3. Normally when you make a function or method call, temporary memory is allocated for the variables local to that function.
    1. This is part of why we talk about "entering a function", you are creating a new memory space & then going inside.
    2. local variables there are "added to the stack" (pushed)
    3. "The stack" is the program's memory.
      1. Like a stack of papers, or a list in lisp -- the last thing you put on is the first thing you see if you are searching.
      2. You'll learn more about stacks from Dr. Paddon.
  4. When you leave the function, the variables aren't needed anymore so they are taken back off the stack (popped).
    1. the program stack is back the way it was before (unless you changed parameters passed by reference)
    2. all the values of function variables are lost.
  5. Once in a while, you don't want this to happen.
    1. Might want to remember a value calculated in a function between calls.
    2. For example, might want to know how often a function addNewUser has been called, so can make a new ID for each user.
  6. To make this happen, you need to ask the compiler to put those variables in permanent memory.
    1. Permanent memory is probably just somewhere very low on the stack.
    2. But anyway, they variable won't get created when you enter the function, or destroyed when you exit.
    3. But they are still private to the function -- no one else can see them.
  7. The way you ask a C compiler to do this is with the keyword static.
    /* returns the current number of users */
    int addNewUser (name)
    char *name;
    {
    static int userID = 0; /*only gets set to 0 the first time the function is called!*/

    addToPasswordFile(name, userID);
    printf ("%s added to password file with userID = %d. There are now %d users.",
    name, userID, ++userID); /*note: this is where userID gets incremented!*/
    return (userID); /* this is now really the number of users */
    } /* addNewUser (name) */
  8. In Java, all memory is kept in an object.
  9. The only memory guaranteed to be around from the beginning to the end of the program is in class objects.
  10. Thus, class variables are sometimes called "static variables."  But this is somewhat naughty...
    1. Class variables are associated with the class & all its instances, not really functions or methods (although of course class's objects' methods can access them).
    2. The fact that they are static is sort of an implementation detail, it's not as salient as the fact they are in the class.
    3. Yet, you have to declare them using the word "static".
      1. No language is perfect!
      2. Java was not designed as a teaching language...
  11. Your first coursework asks you at one pint to put the hash in a class variable.
    1. It would certainly be silly to put a hash in each & every object you are putting in the hash!
    2. Ordinary OOD calls for using two different classes, but we are checking to make sure you have the class variable thing clear.
    3. In fact, the truly ordinary way to do this is to use classes provided in the java library
      1. I suggested doing something similar under "bonus things to do" on Tutorial 2.
      2. Since I don't think anyone got that far in the tutorial, let's have a look at it now (section IV below).
      3. This will also give you important revision on Interfaces, which will be useful when we talk about threading.

III. Inheritance vs. Interface

  1. You should have learned about Interfaces last term, but I'm sure some of you are still confused.
  2. Look at your Blue J book, Chapter 10.
  3. Here's a table to help you think more about this:

    Classes
    Interfaces
    State / Memory / Variables
    yes
    no
    Multiple Inheritance
    no
    (not in Java anyway, can in Lisp)
    yes
    (In Java.  Don't exist in Lisp!)
    Methods / Code
    yes
    only specifications



    Bottom Line
    A real thing you can make instances of.
    A contract you can choose to have your objects meet.
  4. Interfaces are cool because you can have multiple different classes that let you do the same thing in different ways.
    1. If you decide to change the back end of how you do something, all you have to change is the class type of the object that you were having do it.
    2. For example, there are multiple classes for doing hashes provided by Java.  
      1. The one that works with threading is slower than any of the others. 
      2. So you probably wouldn't use it.
      3. But if you decide to convert a non-threaded program into a threaded program, then its easy!
      4. The interface all of these hash classes meet is called Map.
  5. What confuses people sometimes is how interfaces differ from abstract classes.  Abstract classes are classes, not interfaces!

    Concrete
    Abstract
    Class
    yes
    yes
    Interface
    no
    no
    Can make instances of
    yes
    no
    Can inherit from
    yes
    yes
    Can call the methods of
    yes
    as long as they aren't abstract!



    Bottom Line
    A real thing you can make instances of.
    An almost real thing that can be the superclass of a real thing.
  6. What's confusing is that Abstract Classes & Interfaces are both sort of specifications, but they are different sorts.
    1. You can think of abstraction as another kind of privacy -- it's so private it can't even call itself!
    2. You can think of interfaces sort of like contracts or roles
      1. People can have multiple jobs or roles, objects can implement multiple interfaces. 
      2. People can only be of one species, an object can only be of one class.
  7. Sometimes abstract classes are provided to help you implement an interface,
    1. e.g. if you subclass from AbstractMap, you'll have most of what you'll need to implement interface Map.
  8. The idea of abstract classes has been around longer than the idea of interfaces.
  9. Some people think that interfaces are more useful than class hierarchy.

IV. Using the Comparable Interface

  1. Comparable is an interface that lives in Collections & allows you to use Collections.sort().
  2. This is a modification of the program I'm going to show you in Lecture 8.
    1. There's a lot of things in it that don't matter to Comparable that I'll explain tomorrow.
    2. Just pay attention to the bits that are in a colour.
    3. I've switchec these two lectures because I think it makes more sense, even though it was driven by the weird layout of this year's terms.  It shows what they were doing in tutorial 2 right after they did that.
  3. Notice that besides using sort when the user types "sort" (blue), I've also demonstrated the use of class & instance variables (green).
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;

/**
* @author joanna
*
* Demonstrate how to use built-in sorting functions through the
* Comparable interface.
*/
public class SortedBadIndices
implements Comparable {

// class variable holds a list of all instances
private static ArrayList myStuff = new ArrayList();
private int favNumber;

// new constructor to make instances with their favNumber set
// also stores them into myStuff
public SortedBadIndices (int myfav) {
this.favNumber = myfav;
myStuff.add(this);
}

/* (non-Javadoc)
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(Object o) {
if (this.favNumber < ((SortedBadIndices) o).favNumber) {
return -1;
} else if (this.favNumber > ((SortedBadIndices) o).favNumber) {
return 1;
} else { // must be equal!
return 0;
}
} // compareTo (Object o)

public static void main(String[] args) {

// this looks pointless, but in fact the constructor is saving the
// instances into myStuff!
new SortedBadIndices(8); // will be the 0th element.
new SortedBadIndices(5);
new SortedBadIndices(13);
new SortedBadIndices(2);

int newIx = -1;
try {
BufferedReader stdin =
new BufferedReader(new InputStreamReader(System.in));
String myNumString;

System.out.print("Welcome to my program. The prompt looks like >>." +
"\n >> ");
while ((myNumString=stdin.readLine()) != null) {
if (myNumString.equals("sort")) {
Collections.sort(myStuff);
}
else try {
newIx = Integer.decode(myNumString).intValue();
} catch (NumberFormatException nfe) {
System.out.println("you nurf herder, put in integers!");
newIx = 0;
} catch (Exception ex) {
System.out.println("Wow, I didn't expect a " + ex);
} finally {
System.out.println("I have " + newIx + " as my index.");
System.out.flush();
}
try {
System.out.println("The fav number at " + newIx + " is " +
((SortedBadIndices) myStuff.get(newIx)).favNumber);
} catch (IndexOutOfBoundsException iobe) {
System.out.println("We're sorry, " +
"there is no such array element.");
}

System.out.print("\n >> ");
} // while reading
} catch (IOException ioe) {
ioe.printStackTrace(); // printStackTrace is always a useful way to see what happened!
System.exit(-3);
}
} // main()

} // class SortedBadIndices

V. The Class Class

  1. For every class that you use in a program, there's an instance of the class Class.
  2. This makes sense, because where else would the class variables go?  Variables live in objects / instances.
  3. You can do cool things with class Class, e.g.
    1. Find out the class of an object you've been passed.
      String s = "Arvice";
      Class myclass = s.getClass();
      System.out.println(myclass.getName()); // prints "java.lang.String"
    2. Get the class object of something you've heard of.
      try {
      Class sneakersClass = Class.forName("Sneakers");
      } catch (ClassNotFoundExcepiton e) {e.printStackTrace();}
    3. Use the class object to make an instance (assuming we have a good type for the object, in this case an interface...)
      interface Shoe {...
      }

      Shoe shoeish = (Shoe) sneakerClass.newInstance();
  4. These sorts of things are particularly useful if you have been given new code from somewhere, e.g. a plugin from the internet.
  5. We might talk more about this the week after next!
  6. Another related issue (for the keen): Reflection.  See O'Reilly's "Learning Java" by Niemeyer & Knudsen, Chapter 7.
  7. For the less keen, the important thing is to realize that interfaces don't have objects.  They are always purely specifications.

VI. Summary

  1. Variables take space. 
    1. If you think about that space, it makes it more obvious what things are "real", that is, have objects.
  2. Covered classes vs. interfaces, abstract vs. concrete classes, class objects, class variables, and what `static' really means.
  3. Demonstrated using the Comparable interface.
  4. Explained log vs. exp one more time!

page author: Joanna Bryson
12 February 2007