II. Static Memory and Class Variables
- What are class variables & where do they get stored?
- Why do you declare them with the word static?
- We will start out thinking about languages in general,
then look at how early languages like C have impacted Java.
- History affects everything, even programming.
- The basic problems don't change, although on occassion
our approaches to solving them do.
- Normally when you make a function or method call,
temporary memory is allocated for the variables local to
that function.
- This is part of why we talk about "entering a function",
you are creating a new memory space & then going
inside.
- local variables there are "added to the stack" (pushed)
- "The stack" is the program's memory.
- 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.
- You already learned about stacks, right?
- When you leave the function, the variables aren't needed
anymore so they are taken back off the stack (popped).
- the program stack is back the way it was before
- You may have changed parameters passed by reference,
but the referents are probably somewhere else in RAM
than the stack.
- all the values of function variables are lost.
- Once in a while, you don't want this to happen.
- Might want to remember a value calculated in a function
between calls.
- For example, might want to know how often a function
addNewUser has been called, so can make a new ID for each
user.
- To make this happen, you need to ask the compiler to put
those variables in permanent memory.
- Permanent memory is probably just somewhere very low on
the stack.
- But anyway, the variable won't get created when you
enter the function, or destroyed when you exit.
- Instead, created when the program is loaded.
- But they are still private to the function -- no one
else can see them.
- 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) */
- In Java, all memory is kept in an object.
- The only memory guaranteed to be around from the beginning
to the end of the program is in class objects.
- Thus, class variables are sometimes called "static
variables." But this is somewhat naughty...
- 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).
- 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.
- Yet, you have to declare them using the word "static".
- No language is perfect!
- Java was not designed as a teaching language...
- In the old coursework, I used to
ask students to put a hash in a class variable.
- It would certainly be silly to put a hash in each &
every object you are putting in the hash!
- Ordinary OOD calls for using two different classes, but
we were checking to make sure students had the class
variable thing clear.
- In fact, the truly ordinary way to
do this is to use classes provided in the java library
- I suggested doing something
similar under "bonus
things to do" on Tutorial 2.
- Since I don't think anyone got
that far in the tutorial, let's have a look at it now
(section IV below).
- This will also give you
important revision on Interfaces, which will be useful
when we talk about threading.
III. Inheritance vs. Interface
- You should have learned about Interfaces last term, but
I'm sure some of you are still confused.
- Look at the Blue J book, Chapter 10.
- 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.
|
- Interfaces are cool because you can have multiple
different classes that let you do the same thing in
different ways.
- 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.
- For example, there are multiple classes for doing hashes
provided by Java.
- The one that works with
threading is slower than any of the others.
- So you probably wouldn't
use it.
- But if you decide to
convert a non-threaded program into a threaded program,
then its easy!
- The interface all of these hash classes meet is called
Map.
- 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.
|
- What's confusing is that Abstract Classes & Interfaces
are both sort of specifications, but they are different
sorts.
- You can think of abstraction as another kind of privacy
-- it's so private it can't even call itself!
- You can think of interfaces sort of like contracts or
roles
- People can have multiple jobs or roles, objects can
implement multiple interfaces.
- People can only be of one species, an object can only
be of one class.
- Sometimes abstract classes are provided to help you
implement an interface,
- e.g. if you subclass from AbstractMap,
you'll have most of what you'll need to implement
interface Map.
- The idea of abstract classes has been around longer than
the idea of interfaces.
- Some people think that interfaces are more useful than a
class hierarchy.
- 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
- Comparable is an
interface that lives in Collections
& allows you to use Collections.sort().
- This is a modification of the program I'm
going to show you in Lecture 7.
- There's a lot of things in it that don't
matter to Comparable that I'll explain next week.
- Just pay attention to the bits that are
in a colour.
- These two lectures used to
be reversed in order, but I think it makes more sense
this way around.
- 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
- For every class that you use in a program, there's an
instance of the class Class.
- This makes sense, because where else would the class
variables go? Variables live in objects / instances.
- You can do cool things with class Class, e.g.
- 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"
- There's many more things you can do with this, but we'll talk about
them after we've talked about errors...
VI. Summary
- Variables take space.
- If you think about that space, it makes it more obvious
what things are "real", that is, have objects.
- Covered classes vs. interfaces, abstract vs. concrete
classes, class objects, class variables, and what `static'
really means.
- Demonstrated using the Comparable interface.
- Explained log vs. exp one more time!