Welcome to Using Classes

You saw in the last lesson how to define classes, how to extend classes, and how to add variables and methods to classes. Now, you wisely ask, just what the frag is a class?!?

We've already talked a little about objects, and you should have some idea what an object is. Well, classes are were objects come from. A class is to an object, as a data type is to a variable. (And you thought you didn't need English to program!) In geek speak that is, "An object is an instantiation of a class."

O.K., so you don't remember what an object is really. Let's go back over them briefly. Objects are the basic building block of an object-oriented program. Each object contains some data and the functions (called methods) which act on that data. For instance, say we have an object that is a stack. It will have an array to store the data in and push() and pop() methods for accessing the array. The power of objects comes from the fact that the data array can only be accessed through push() and pop().
The Stack class is the code that is used to instantiate the stack object. Here's a brief example:

public class Stack { private int[] data_array; private int current=0; public int pop () { if (current != 0) return(data_array[current--]); else return(-1); } public void push (int data) { data_array[++current] = data; } } public class Test { public Stack my_stack; public void PushNPop () { int value; my_stack.push(5); my_stack.push(10); value = my_stack.pop(); } } I have left out a couple of details, such as initializing the data_array, but that's not important right now.
What I have done is create a Stack class. It has an array for data, a variable to keep track of what the top of the stack is, and push() and pop() methods. Notice that the pop() method will return -1 if the stack is empty.
I then created another class called Test which uses a stack object called my_stack. It has a PushNPop() method which pushes and pop the stack.

Let's look a little more closely. First of all, what do all the public and privates mean? Public means anyone can see the variable or use the method or instantiate the class. Private means only methods within the class can use the variable or use the method. Very seldom will you see a private class.
In the Stack class, data_array and current are private. That means only the push() and pop() methods can use them. So, the only way you can access the contents of the stack is through those methods. The methods themselves are public, meaning anyone can use them, just as Test does.

Second, notice how PushNPop() called the push() and pop() methods. When you call a methods, you must specify which object's methods you're calling. That is done with the "." operator. So, my_stack.pop() says to call the pop() method of the object my_stack. Notice also that pop() does return a value. Why is it worth doing all that work for just a stack? Well, look at it this way: When PushNPop() calls pop(), does it have to worry about whether the stack is empty or not? Does PushNPop() even know how the stack is stored? No. We could completely reformat the Stack class, and so long as it still has a pop() method that returns an interger, PushNPop() will never know the difference.

For another advantage, let's look at another piece of code:

public class Test2 { public Stack stack1,stack2; public PushNPop () { stack1.push(1); stack1.push(5); stack2.push(stack1.pop()); stack2.push(stack1.pop()); } } Now we're handling two separate stacks. PushNPop() pushes two numbers onto stack1 and then pops them off and pushes them onto stack2. Try doing that as easily without the use of objects!

Here we also see why we must use the "." when calling a method. Because we can have more than one object of the same class, we must specify which object's method we're calling.

By the way, in case you're wondering, after executing PushNPop(), stack1 will contain nothing, and stack2 will contain {5,1}. (From this point onward, I will assume you're sold on the idea of objects. I'll concentrate instead on selling you on Java.)

One of the great things about Java is it's huge class library. Java has a very large library of predefined classes that you can use. For instance, our Stack class is not necessary since it is already defined in Java's class library.

A very important class in the Java class library is the Applet class. You've seen a little of the Applet class in the previous lesson. (Brief side note on naming conventions.) The Applet class is the class from which all applets are derived. Every applet must inherit from java.applet.Applet somewhere along the line. Inheritance is a way for a class to gain all of the properties and abilities of another class. In Java, the extends keyword is used to declare inheritance for a class. The Applet class has the ability to interface with Netscape and other browsers.

The Applet class has four important methods: init(), start(), paint(), and stop(). These four methods are the ones called by Netscape when it wants to run the applet. The first time it tries to run the applet, Netscape will call the init() method. The init() method is used to do variable initializations and other things that need to be done before the applet runs, and that only need to be done once. Next, Netscape calls start(). The start() method is the once that gets things going. It starts the applet doing whatever it does. When Netscape needs the applet to display itself, it calls the paint() method. The paint() methods should draw everything on the screen that needs to be drawn. Finally, when the user goes to another page, Netscape calls the stop() method. stop() should kill all of the applet's active processes and generally gets things cleaned up and ready to quit. Let's look at some examples.

import java.applet.*; import java.awt.*; public class HelloWorldApplet extends Applet { public void paint(Graphics g) { g.drawString("Hello World", 25, 50); } }

This is the same example we saw earlier. First, you see that this HelloWorldApplet extends Applet. By inheriting from Applet, HelloWorldApplet gains the ability to interface with web browsers.
Second, notice that this class only has a paint() method. Where are the other methods like init() and start()? Well, the answer has to do with inheritance. Since HelloWorldApplet is a child of Applet, it inherits all of Applet's non-private variables and methods. So, HelloWorldApplet has the same init(), paint(), start(), etc. as Applet. Then why does HelloWorldApplet define a paint() method if it already has one it inherited from Applet? Well, the paint() method inherited from Applet is a generic paint() method that really doesn't do anything. So, HelloWorldApplet has to override Applet's paint() method with its own. That way, HelloWorldApplet has a paint() method which does specifically what it needs. Any time a class redefines one of it's parent's methods or vartiables, it's called overriding.

import java.applet.*; import java.awt.*; public class HelloWorldApplet2 extends Applet { private String print_string; public void init() { print_string = "Hello World"; } public void paint(Graphics g) { g.drawString(print_string, 25, 50); } }

Now we changed things a little. We've added a private variable and an init() method. Why? No reason really. I just wanted to make the example a little more complex. Let's look at the differences between the last class and this one.
First, the patin() method has changed a little. Instead of passing it a string of text, we're now passing it a variable. The variable print_string is declared outside of the methods of the class, so it is "global" within the class. That means that any method in the class can use it and/or change it's value. (Java claims to not allow any global variables, which is true, but I can't think of a better word to use.) So, now that we have this variable, we have to initialize it somewhere. What better place than in the init() method? The init() method will be called exactly once per use of the applet. That means that init() will be run the first time you view the page, but if you go to another page and come back, it won't be run again. You'll have to reload Netscape to get the init() method to run again.

import java.applet.*; import java.awt.*; public class HelloWorldApplet3 extends Applet { private String print_string; private int view_count; public void init() { print_string = "Hello World"; view_count = 0; } public void start() { view_count++; } public void paint(Graphics g) { g.drawString(print_string + ": " + view_count, 25, 50); } }

Now we've changed things around again. We've added a new private variable and a start() method. The init() method now also sets the view_count variable to zero. The start() method increments the view_count variable by one. The start() method is called everytime the applet is started or restarted. So, view_count will be incremented everytime the applet is viewed. The paint() method now also prints the number of times the applet has been viewed since the last time Netscape was loaded. Note, this cannot be used as a web counter because every user will have their own copy of the applet, and it will be reset to zero for that user everytime they load Netscape or flush Netscape's cache.

Alright, that should be enough about the Applet class for now. Let's look at another very important class, Graphics.
The Graphics class is the one that allows you use to do absolutely everything you can see in an applet. In the above examples, we used the Graphics class to write the string to the screen. Stand-alone application can also use the Graphics class, but they do not have to. They can also provide plain text output.

The Graphics class is actually java.awt.Graphics, which is why the above examples had to include the "import java.awt.*;" line. All applet have a Graphics object associated with them. Many other objects in Java's class library have associated Graphics objects. It is by using these Graphics objects, that we do all graphical output. Let's look at a few of the more useful methods in Graphics.

MethodWhat it does
clearRect(int x, int y, int width, int height) Clears a rectangular area width x height, with the upper left corner at (x,y)
drawLine(int x1, int y1, int x2, int y2) Draws a line from (x1,y1) to (x2,y2)
drawOval(int x, int y, int width, height) Draws an oval with width width and height height, with it's center at (x,y)
drawRect(int x, int y, int width, int height) Draw a rectangle width x height, with the upper left corner at (x,y)
drawSting(String str, int x, int y) Prints str on the screen starting a little above (x,y)
fillOval(int x, int y, int width, height) Draws a filled oval. Uses same parameters as drawOval
fillRect(int x, int y, int width, height) Draws a filled rectangle. Uses same parameters as drawRect
getColor() Returns the current color being used in the Graphics object
getFont() Returns the current font being used in the Graphics object
setColor(Color c) Sets the current color being used in the Graphics object
setFont(Font font) Sets the current font being used in the Graphics object

Now, let's see how all these things are used.

import java.applet.*; import java.awt.*; public class HelloWorldApplet4 extends Applet { public void paint(Graphics g) { g.setColor(Color.cyan); g.fillOval(13,21,125,50); g.setColor(Color.black); g.setFont(new Font("TimesRoman", Font.PLAIN, 20)); g.drawString("Hello World", 25, 50); g.setColor(Color.red); g.drawLine(25,55,125,55); g.setColor(Color.blue); g.drawRect(11,19,129,54); } }

This example shows how to set the color, set the font, and draw some basic shapes. Notice that g is a Graphics object passed to the paint() method by the web browser when it's called. g is the Graphics object associated with the HelloWorldApplet. A special method of Applet, getGraphics(), returns the Graphics object associated with the applet so it can be used.

O.K. Now we've seen how to do all kinds of neato static graphical stuff with Java. To finish this up, we'll look at a more complex example. This one prints a phrase in a cascading fashion down the screen.

import java.applet.*; import java.awt.*; public class CascadeApplet extends Applet { protected int height; protected int width; protected int num_iter; protected int size_iter; protected int base_size; protected String font_name; protected String print_string; public void init () { height = 300; width = 200; num_iter = 11; size_iter = 3; base_size = 10; font_name = "TimesRoman"; print_string = "Java is neato!"; } public void paint (Graphics g) { Font font; FontMetrics fm; int font_size = base_size; int x_coord = 10; int y_coord = 10; g.setColor(Color.blue); g.clearRect (0, 0, width, height); font = new Font(font_name, Font.BOLD, font_size); g.setFont(font); fm = g.getFontMetrics(); y_coord = 5 + fm.getAscent(); for (int count=0; (count < num_iter) && (y_coord < height); count++) { font = new Font(font_name, Font.BOLD, font_size); g.setFont(font); g.drawString (print_string, x_coord, y_coord); font_size += size_iter; y_coord += font_size; } } }

Everything here should look pretty familiar except the font manipulations. FontMetrics is a class used to get statistics on a particular font, such as how high a letter would be, etc.. Here we use it to make sure the first line printed is fully visable. The ascent and descent of a font are measurements used in type setting. The ascent is the distance from the top of the font to the baseline. The descent is the distance from the baseline to the bottom. Java always puts the baseline of the font at the specified (x,y) coordinate when printing text graphically. So, we moved it down a distance equal to the ascent.
If that didn't make any sense, don't worry. I'm still not sure I understand it fully.

This is also the first time we've seen any looping structures in Java. As you probably noticed, the for loop in Java is identical to the for loop in C or C++. In fact, for loops, while loops, do-while loops, if statements, and case statements are all the same in Java as in C or C++.

Alright, you should now have a reasonable grasp of the way classes work in Java. You've also seen the Applet and Graphics classes in action. The hardest thing about Java is learning how to use Java's class library. It's something that you just have to get used to. For some practice, try doing the Using Classes Homework.

In the next lesson, Advanced Classes, we'll learn inheritance and constructors, and we'll work some more with the Applet and Graphics classes.

Next Lesson: Advanced Classes

Return to the Main Menu.