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...
|