<%@ EnableSessionState=true %> <% Option Explicit dim thisurl thisURL=Request.ServerVariables("PATH_INFO") & "?" & Request.ServerVariables("QUERY_STRING") const title="Java Games tutorial #2 - Console App Redux" %>
Current area: HOME -> Java Games tutorial #2 - Console App Redux

Java Games tutorial #2 - Console App Redux

In the last section, we created a class and edited that class' file to include the main method. Previously, we discussed frameworks and objects--we never mentioned classes. In this section, we'll bridge the gap between classes and objects. That should help cement the connection between our definition of a framework and the work we just completed.

So, how does an object relate to a class?

The simple answer is this: objects are just particular examples of classes. Said another way, classes are like rubber stamps, and objects like the images they produce.

As an example, consider pickup trucks. We could talk about Chevy S-10s in general--that would be like talking about a class--or we could talk about a particular S-10 that's parked down the street--that would be talking about an object.

Coming back to what we just did, we created a class called ConsoleApp. That's the general specification from which Java can create individual objects when the program runs.

Before we get into the particulars of the code, let's review the basic structure of an object as shown in Figure 1. Objects contain variables and methods. Classes define objects. This means that classes must have "boundaries" that "enclose" the data and actions associated with an object.

Try to imagine writing out this information. It would have to look something like this:

HERE IS MY NEW CLASS CALLED myClassName.

HERE IS MY STARTING "CLASS BOUNDARY".

    HERE IS MY FIRST VARIABLE.

    HERE IS VARIABLE #2.

    ...

    HERE IS MY LAST VARIABLE.

 

    HERE IS MY FIRST ACTION.

    HERE IS ACTION #2.

    ...

    HERE IS MY LAST ACTION.

HERE IS MY ENDING "CLASS BOUNDARY."

(where the ellipsis (...) means 'lines similar to the one above go here'.)

Now consider some of Java's rules for defining a class:

1) The keyword class signals the start of a class definition, and must immediately precede the class name.

2) Curly braces ('{' and '}') are used as "boundary markers". The opening brace starts a section and the corresponding closing brace ends it.

3) Sections can contain other sections, in which case the braces are "nested". For example, in the following code, section 1 contains section 2:

{ // This is the start of section 1.

 

    { // This is the start of section 2.

    } // This is the end of section 2.

 

} // This is the end of section 1.

Applying these rules to our naive attempt to write a class definition, we see that it reduces to:

class myClassName.

{

    HERE IS MY FIRST VARIABLE.

    HERE IS VARIABLE #2.

    ...

    HERE IS MY LAST VARIABLE.

 

    HERE IS MY FIRST ACTION.

    HERE IS ACTION #2.

    ...

    HERE IS MY LAST ACTION.

}

Where the green indicates places where actual Java has replaced our original notation.

Now consider some of Java's rules for defining variables:

1) The first part of the definition must define the variable's type (i.e., the kind of information it can hold). Examples of valid types are int--short for 'integer'--which holds numbers without decimals (like 1, -99, and 0); float--short for 'floating point'--which are numbers with decimals (like 3.1415926 and -0.3); and String--collections of letters, numbers, and symbols strung together (like "Keep off the Grass", "THX-1138", and "5793").

2) The variable's name must immediately follow its type.

3) The line must end with a semicolon (;).

Again, applying these to our example, we get:

class myClassName.

{

    type variableName1;

    type variableName2;

    ...

    type variableNameN;

 

    HERE IS MY FIRST ACTION.

    HERE IS ACTION #2.

    ...

    HERE IS MY LAST ACTION.

}

Where the blue type indicates areas to which we've applied the new rules.

Lastly, consider some of Java's rules for defining methods (i.e., actions):

1) The first part of a method definition must describe the type of the result produced. For example, an object might have an 'add' method that produces in integer result. In that case the method definition would start with 'int'.

2) If a method produces no result, its definition must begin with 'void'.

3) The method name must immediately follow the result type.

4) An open parenthesis must immediate follow the method's name.

5) A list of the methods arguments must follow this parenthesis (arguments are numbers, Strings, or Objects the method will use to calculate its result).

6) A closing parenthesis must immediately follow the last argument. If the method takes no arguments, an open/close parenthesis pair must follow the method name.

7) A set of curly braces will denote the start and end of the method's body.

That's a lot of rules, but they're all pretty simple. Applying them to our example, we get:

class myClassName.

{

    type variableName1;

    type variableName2;

    ...

    type variableNameN;

 

    type method1(type arg1, type arg2, ...) {

        // Method body goes here.

    }

 

    type method2(type arg1, type arg2, ...) {

        // Method body goes here.

    }

 

    ...

 

    type methodN(type arg1, type arg2, ...) {

        // Method body goes here.

    }

}

Now let's pick apart the ConsoleApp's actual code.

First, there's

/**
 * A blank console application, ripe with
possibility.
 * 
 * @author Mark Kreitler 
 * @version v0.1
 */

You might recall from the first tutorial that any text enclosed in /* ... */ blocks is a comment. Similarly, any line following a // is comment. Java ignores comments--they're only useful to humans reading the code. We'll use them  heavily to describe what we're doing inside the classes, but the computer couldn't care less, so let's move on.

Removing the comments, we get:

public class ConsoleApp
{
    public static void main(String[] args) {
    }
}

Breaking this down using the color coding above, we see the following:

 

public class ConsoleApp
{

    public static void main(String[] args) {
    }

}

Where green shows the overall class definition, and ochre shows a method definition.

 

Ignoring the 'public' and 'static' qualifiers for the moment, we can immediately see that there are no variables associated with this class (hence no blue text), and there is but a single method--main.

Now--what about the word 'public'. What could that mean?

Well, the traditional definition boils down to, "open to everyone." It's pretty much the same in Java. When you declare a class as 'public', any other object can create an object of the specified type. In our case, any object in our program could create a ConsoleApp. Of course, currently, ConsoleApp is the only object in the project, so this is a moot point--for now.

Classes can also be declared 'private' (no outside objects can create the class) and 'protected' (which is somewhere in between public and private. We'll talk about this more in a later tutorial).

That takes care of the class definition--now what about the method?

We'll pick the details apart in a minute--but first, let's take a look at methods in another light.

Getting into the Meat of Programming

As we've said, a 'method' is an action an object can perform. More precisely, a method consists of a set of instructions that accept a list of arguments, manipulate them, and possibly return a result.

In other words, a method is a small, self-contained program that accepts data, manipulates it, and produces output.

Programs within programs? Yes--and you'd better get used to it. Programming is full of this kind of thing.

Personally, I like to think of methods as meat grinders. You put something in. You turn the crank. You get something out (usually).

Figure 5 -- Methods as Meat Grinders.

What do methods take in? Arguments. What's an argument? It's just a piece of data of the types we've already mentioned: integers, floating point numbers, Strings, other objects, etc.

What do methods produce? Results. What's a result? Same thing as an argument: integers, floating point numbers, etc. The trick here is that methods can only produce one result, while they can accept many arguments. Of course, methods can produce no results, too.

Let's re-examine our current method definition in light of the meat grinder analogy.

 

public static void main(String[] args) {

}

 

The word 'public' tells us who can turn the crank. If it's public, anyone can. If it's private, only this objects can. If it's protected, it's somewhere in between. In this way, 'public' here works just like it did in the class definition.

 

The word 'static' tells us that there's only one copy of this method that's shared by all the objects in the class. Without 'static', each object would have its own local copy. The following figures illustrate the difference.

 

Figure 6 -- Methods Without the 'Static' Modifier: each object gets one.

 

 

Figure 7 -- Static Methods: objects share one copy.

 

Now all that remains is:

 

void main(String[] args)

 

and the curly braces. We know from the above rules that the curly braces just mark the beginning and end of the method, so let's move on to 'void' and the stuff in parentheses.

 

Once more, the meat grinder comes in handy. The word before the method name tells us the result the grinder spits out. Here are some examples:

 

int add()               // Result is an integer.

String getName()        // Result is a String.

Object myCoolFunction() // Result is an Object.

 

So, main returns a void result. What does that mean? Well, in everyday language, void means "empty" or "nothingness". So the main method returns nothing.

 

Which brings us to the stuff in parentheses. These are the arguments we put into the method (i.e., the stuff you put in the grinder before turning the crank).

 

Arguments are just variables used in the method. As with the variable definitions for the class, Java requires two pieces of information: a variable type and a variable name.

 

So,

 

String[] args

 

tells us the type (String[]) and the name ('args').

 

Now we see something new. We're familiar with Strings--they're just collections of symbols (remember the earlier definition?)--but what are these brackets('[' and ']')?

 

Java uses brackets to denote an 'array'.  'Array' is just a fancy way of saying 'list' (ok--technically, that's not accurate, but it works for now. We'll get into arrays more deeply in a future tutorial). Why brackets? Java provides them so we can access a particular member of the list.

 

Suppose you have an array of Strings called Hobbits that contains the following data:

 

"Bilbo"

"Frodo"

"Merry"

"Pippin"

 

How could you access the second element (i.e., "Frodo")?

 

In Java, you would type the following: Hobbits[1].

 

I can hear you saying, "Wait a minute! Hobbits[1]? Why isn't it Hobbits[2]?!"

 

Java, like C and C++, starts counting array elements from 0, not 1. So

 

Hobbits[0] contains "Bilbo",

Hobbits[1] contains "Frodo",

etc.

 

That's probably the most confusing part of the language, especially for beginners.

 

But we digress. Getting back to main, we now see that it takes a list of Strings as its argument.

 

Let's summarize what we know about the method main:

  • It's public, which means anyone can access it.

  • It's static, which means there's only one copy shared amongst all ConsoleApps we create.

  • It returns a void result, which means it doesn't really return anything at all.

  • It's called main--but we already knew that.

  • It takes a single argument called 'args' that consists of an array of Strings, indicated by the keyword String[].

That pretty much wraps it up for the class definition. In the next section, we'll actually write some code, so let's not waste any time.

 

On to the FABconsole app...