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 howearly languages like C have impacted Java.
- History affects everything, even programming.
- The basic problems don't change, although our approaches to
solving them do a bit.
- 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'll learn more about stacks from Dr. Paddon.
- 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 (unless you
changed parameters passed by reference)
- 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, they variable won't get created when you enter the
function, or destroyed when you exit.
- 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...
- Your first coursework asks you at one
pint to put
the 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 are
checking to make sure you have 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 your 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
|
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 class
hierarchy.
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 8.
- There's a lot of things in it that don't
matter to Comparable that I'll explain tomorrow.
- Just pay attention to the bits that are
in a colour.
- 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.
- 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
- 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"
- Get the class object of something you've heard of.
try {
Class sneakersClass = Class.forName("Sneakers");
} catch (ClassNotFoundExcepiton e) {e.printStackTrace();}
- 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();
- These sorts of things are particularly useful if you have been
given new code from somewhere, e.g. a plugin from the internet.
- We might talk more about this the week after next!
- Another related issue (for the keen): Reflection. See
O'Reilly's "Learning Java" by Niemeyer & Knudsen, Chapter 7.
- For the less keen, the important thing is to realize that
interfaces don't
have objects. They are always purely specifications.
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!