CM10228 / Programming Ib:   Lecture 6


Space, Class, Polymorphism & Interfaces


-I. Housekeeping / Time Management

  1. Reminder:  This is a double unit!  So you should be spending 200 hours on it.
    1. 30 one hour lectures
    2. 10 two hour labs
    3. 150 hours you spend on your own!
    4. 12 hours a week!!
      1. Might want to spend one or two hours reading over the lecture notes every week.
      2. The rest is programming.  Don't leave 30-40 hours of programming to do the week a CW is due.
      3. Unless you are a great programmer, you should be showing up to labs & working on at least the plan for your CW1.
  2. Being a student is a full time job.  5 units take 100 hours each over a 12 week period
    1. 500 / 12 = 42 hours a week.
    2. As teenagers you should probably be sleeping 8.5 hours a night -- 60 hours a week.
    3. This leaves you 66 hours a week to do what you like in!
      1. Even if you spend 3 hours a day doing meals, that leaves 45 other hours --- more than you need to spend on your studies.
    4. Unlike real jobs, you get to largely pick when you work (e.g. doing some on weekends rather than putting in a full 8 hour day every week day.)
    5. Unless you did no programming before you came here, first year is far easier than second year.
      1. All the years are roughly the same if you are struggling with programming your first year.
    6. If you can't find time, you are probably having time management issues.
      1. University of Bath's Student Time Management Page.
      2. Suggestions and forms from Chicago (coincidently, where I went to Uni, though a few years ago it was just what came up first / best with Google).
  3. Definition of default (as in "default values" -- adjective / noun).
  4. Ask courswork questions on the Moodle forums
    1. This way tutors only have to answer a question once.
    2. This way everyone gets the same (and same quality) answer.
    3. You can get answers from each other
      1. The best way to learn is to teach.
      2. Tutors are less likely to be awake at 4am than undergraduates.
  5. Another version of table from last time:

    complexity
    linear (unsorted list)
    linear on n
    linear (sorted list)
    linear on n
    binary (sorted list only!)
    log n
    array
    constant on n
    hash (chained)
    constant on n, linear on alpha
    hash (probing)
    constant on n, exponential on alpha
    Note that depending on how many times you are going to search your data structure, the cost of sorting in the first place may be irrelevant.

I. The Big Picture

  1. The main theme of this lecture (as with Lecture 1) is visualizing memory --- understanding where it is.
    1. Everything has to be in memory somewhere --- including the program itself!
    2. Thinking clearly about memory (state) is absolutely critical to thinking clearly about programs, systems & algorithms.
      1. You need to know what you need, and when you need it, and what form it should be in.
  2. Pop quiz:  What is polymorphism?
    1. Here's some good notes about it.
    2. Polymorphism is a simple concept -- just the same method can apply to different objects.  This can be done in different ways:
      1. Overloading means that the things really are fundamentally different, and may even have a different signature.
      2. Overridden means that a subclass has redefined something in a superclass.  This has to have the same signature.
      3. Dynamic Binding means that a single call in code may be talking about different kinds of objects, but dynamically (at run time) it can figure out which method to call based on which object is referenced.
      4. public class AnimalArray
        {
        public static void main(String args[])
        Animal ref[] = new Animal[3]; // assign space for array
        Cow aCow = new Cow("Bossy"); // makes specific objects
        Dog aDog = new Dog("Rover");
        Snake aSnake = new Snake("Earnie");

        // now put them in an array
        ref[0] = aCow; ref[1] = aDog; ref[2] = aSnake;

        // now demo dynamic method binding
        for (int x=0;x<3;++x) { ref[x].speak(); }
        } // this example was from the link above

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 how early languages like C have impacted Java.
    1. History affects everything, even programming.
    2. The basic problems don't change, although on occassion our approaches to solving them do.
  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 already learned about stacks, right?
  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
      1. You may have changed parameters passed by reference, but the referents are probably somewhere else in RAM than the stack.
    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, the variable won't get created when you enter the function, or destroyed when you exit.
      1. Instead, created when the program is loaded.
    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. In the old coursework, I used to ask students to put a 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 were checking to make sure students had 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 the 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
    Has state
    yes
    yes
    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 a class hierarchy.
    1. These things are open to debate!  You are at the bleeding edge of software engineering now, you're computer scientists.

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 7.
    1. There's a lot of things in it that don't matter to Comparable that I'll explain next week.
    2. Just pay attention to the bits that are in a colour.
    3. These two lectures used to be reversed in order, but I think it makes more sense this way around.
  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; boolean justSortedP=false;
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); justSortedP=true;
}
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 {
if (justSortedP==true) {
System.out.println("sorted"); justSortedP=false;
} else {
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. There's many more things you can do with this, but we'll talk about them after we've talked about errors...

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
19 February 2015