CERTIFICATION OBJECTIVE
Define Classes
(OCA Objectives 1.2, 1.3, 1.4, 6.6, and 7.6)
1.2 Define the structure of a Java class.
1.3 Create executable Java applications with a main method.
1.4 Import other Java packages to make them accessible in your code.
6.6 Apply access modifiers.
7.6 Use abstract classes and interfaces.
When you write code in Java, you're writing classes or interfaces. Within those
classes, as you know, are variables and methods (plus a few other things). How you
declare your classes, methods, and variables dramatically affects your code's behavior.
For example, a public method can be accessed from code running anywhere in your
application. Mark that method private , though, and it vanishes from everyone's
radar (except the class in which it was declared).
For this objective, we'll study the ways in which you can declare and modify (or
not) a class. You'll find that we cover modifiers in an extreme level of detail, and
although we know you're already familiar with them, we're starting from the very
beginning. Most Java programmers think they know how all the modifiers work, but
on closer study they often find out that they don't (at least not to the degree needed
for the exam). Subtle distinctions are everywhere, so you need to be absolutely certain
you're completely solid on everything in this section's objectives before taking the exam.
Source File Declaration Rules
Before we dig into class declarations, let's do a quick review of the rules associated with
declaring classes, import statements, and package statements in a source file:
■ There can be only one public class per source code file.
■ Comments can appear at the beginning or end of any line in the source code
file; they are independent of any of the positioning rules discussed here.
■ If there is a public class in a file, the name of the file must match the name
of the public class. For example, a class declared as public class Dog { }
must be in a source code file named Dog.java .
■ If the class is part of a package, the package statement must be the first line
in the source code file, before any import statements that may be present.
■ If there are import statements, they must go between the package statement
(if there is one) and the class declaration. If there isn't a package statement,
then the import statement(s) must be the first line(s) in the source code file.
If there are no package or import statements, the class declaration must be
the first line in the source code file.
■ import and package statements apply to all classes within a source code file.
In other words, there's no way to declare multiple classes in a file and have
them in different packages or use different imports.
■ A file can have more than one nonpublic class.
■ Files with no public classes can have a name that does not match any of the
classes in the file.
Using the javac and java Commands
In this book, we're going to talk about invoking the javac and java commands
about 1000 times. Although in the real world you'll probably use an integrated
development environment (IDE) most of the time, you could see a few questions on
the exam that use the command line instead, so we're going to review the basics.
(By the way, we did NOT use an IDE while writing this book. We still have a slight
preference for the command line while studying for the exam; all IDEs do their best
to be "helpful," and sometimes they'll fix your problems without telling you. That's
nice on the job, but maybe not so great when you're studying for a certification exam!)
Compiling with javac
The javac command is used to invoke Java's compiler. You can specify many
options when running javac . For example, there are options to generate debugging
information or compiler warnings. Here's the structural overview for javac :
javac [options] [source files]
There are additional command-line options called @argfiles , but they're rarely
used, and you won't need to study them for the exam. Both the [options] and the
[source files] are optional parts of the command, and both allow multiple
entries. The following are both legal javac commands:
javac -help
javac -version Foo.java Bar.java
The first invocation doesn't compile any files, but prints a summary of valid
options. The second invocation passes the compiler an option ( -version , which
prints the version of the compiler you're using), and passes the compiler two .java
files to compile ( Foo.java and Bar.java ). Whenever you specify multiple options
and/or files, they should be separated by spaces. (Note: If you're studying for the
OCP 7, in Chapter 7 we'll talk about the assertion mechanism and when you might
use the -source option when compiling a file.)
Launching Applications with java
The java command is used to invoke the Java Virtual Machine (JVM). Here's the
basic structure of the command:
java [options] class [args]
The [options] and [args] parts of the java command are optional, and they
can both have multiple values. (Of the two exams, only the OCP 7 will use
[options] .) You must specify exactly one class file to execute, and the java
command assumes you're talking about a .class file, so you don't specify the
.class extension on the command line. Here's an example:
java -version MyClass x 1
This command can be interpreted as "Show me the version of the JVM being
used, and then launch the file named MyClass.class and send it two String
arguments whose values are x and 1 ." Let's look at the following code:
public class MyClass {
public static void main(String[] args) {
System.out.println(args[0] + " " + args[1]);
}
}
It's compiled and then invoked as follows:
java MyClass x 1
The output will be
x 1
We'll be getting into arrays in depth later, but for now it's enough to know that
args—like all arrays—uses a zero-based index. In other words, the first command line
argument is assigned to args[0] , the second argument is assigned to args[1] , and
so on.
Note: Again, for the OCP 7 candidates, in Chapter 7 we'll talk about the
assertion mechanism and when you might use flags such as -ea or -da when
launching an application.
Using public static void main(String[ ] args)
The use of the main() method is implied in most of the questions on the exam, and
on the OCA exam it is specifically covered. For the .0001% of you who don't know,
main() is the method that the JVM uses to start execution of a Java program.
First off, it's important for you to know that naming a method main() doesn't
give it the superpowers we normally associate with main(). As far as the compiler
and the JVM are concerned, the only version of main() with superpowers is the
main() with this signature:
public static void main(String[] args)
Other versions of main() with other signatures are perfectly legal, but they're
treated as normal methods. There is some flexibility in the declaration of the
"special" main() method (the one used to start a Java application): the order of its
modifiers can be altered a little, the String array doesn't have to be named args ,
and as of Java 5 it can be declared using var-args syntax. The following are all legal
declarations for the "special" main() :
static public void main(String[] args)
public static void main(String... x)
static public void main(String bang_a_gong[])
For the OCA exam, the only other thing that's important for you to know is that
main() can be overloaded. We'll cover overloading in detail in the next chapter.
Import Statements and the Java API
There are a gazillion Java classes in the world. The Java API has thousands of classes
and the Java community has written the rest. We'll go out on a limb and contend
that all Java programmers everywhere use a combination of classes they wrote and
classes that other programmers wrote. Suppose we created the following:
public class ArrayList {
public static void main(String[] args) {
System.out.println("fake ArrayList class");
}
}
This is a perfectly legal class, but as it turns out, one of the most commonly used
classes in the Java API is also named ArrayList , or so it seems.... The API
version's actual name is java.util.ArrayList . That's its fully qualified name. The
use of fully qualified names is what helps Java developers make sure that two
versions of a class like ArrayList don't get confused. So now let's say that I want to
use the ArrayList class from the API:
public class MyClass {
public static void main(String[] args) {
java.util.ArrayList<String> a =
new java.util.ArrayList<String>();
}
}
(First off, trust us on the <String> syntax; we'll get to that later.) While this is
legal, it's also a LOT of keystrokes. Since we programmers are basically lazy (there,
we said it), we like to use other people's classes a LOT, AND we hate to type. If we
had a large program, we might end up using ArrayList s many times.
import statements to the rescue! Instead of the preceding code, our class could
look like this:
import java.util.ArrayList;
public class MyClass {
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
}
}
We can interpret the import statement as saying, "In the Java API there is a
package called 'util', and in that package is a class called 'ArrayList'. Whenever you
see the word 'ArrayList' in this class, it's just shorthand for: 'java.util.ArrayList'."
(Note: Lots more on packages to come!) If you're a C programmer, you might think
that the import statement is similar to an #include . Not really. All a Java import
statement does is save you some typing. That's it.
As we just implied, a package typically has many classes. The import statement
offers yet another keystroke-saving capability. Let's say you wanted to use a few
different classes from the java.util package: ArrayList and TreeSet . You can
add a wildcard character ( * ) to your import statement that means, "If you see a
reference to a class you're not sure of, you can look through the entire package for
that class," like so:
import java.util.*;
public class MyClass {
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
TreeSet<String> t = new TreeSet<String>();
}
}
When the compiler and the JVM see this code, they'll know to look through
java.util for ArrayList and TreeSet . For the exam, the last thing you'll need to
remember about using import statements in your classes is that you're free to mix
and match. It's okay to say this:
ArrayList<String> a = new ArrayList<String>();
java.util.ArrayList<String> a2 = new java.util.ArrayList<String>();
Define Classes
(OCA Objectives 1.2, 1.3, 1.4, 6.6, and 7.6)
1.2 Define the structure of a Java class.
1.3 Create executable Java applications with a main method.
1.4 Import other Java packages to make them accessible in your code.
6.6 Apply access modifiers.
7.6 Use abstract classes and interfaces.
When you write code in Java, you're writing classes or interfaces. Within those
classes, as you know, are variables and methods (plus a few other things). How you
declare your classes, methods, and variables dramatically affects your code's behavior.
For example, a public method can be accessed from code running anywhere in your
application. Mark that method private , though, and it vanishes from everyone's
radar (except the class in which it was declared).
For this objective, we'll study the ways in which you can declare and modify (or
not) a class. You'll find that we cover modifiers in an extreme level of detail, and
although we know you're already familiar with them, we're starting from the very
beginning. Most Java programmers think they know how all the modifiers work, but
on closer study they often find out that they don't (at least not to the degree needed
for the exam). Subtle distinctions are everywhere, so you need to be absolutely certain
you're completely solid on everything in this section's objectives before taking the exam.
Source File Declaration Rules
Before we dig into class declarations, let's do a quick review of the rules associated with
declaring classes, import statements, and package statements in a source file:
■ There can be only one public class per source code file.
■ Comments can appear at the beginning or end of any line in the source code
file; they are independent of any of the positioning rules discussed here.
■ If there is a public class in a file, the name of the file must match the name
of the public class. For example, a class declared as public class Dog { }
must be in a source code file named Dog.java .
■ If the class is part of a package, the package statement must be the first line
in the source code file, before any import statements that may be present.
■ If there are import statements, they must go between the package statement
(if there is one) and the class declaration. If there isn't a package statement,
then the import statement(s) must be the first line(s) in the source code file.
If there are no package or import statements, the class declaration must be
the first line in the source code file.
■ import and package statements apply to all classes within a source code file.
In other words, there's no way to declare multiple classes in a file and have
them in different packages or use different imports.
■ A file can have more than one nonpublic class.
■ Files with no public classes can have a name that does not match any of the
classes in the file.
Using the javac and java Commands
In this book, we're going to talk about invoking the javac and java commands
about 1000 times. Although in the real world you'll probably use an integrated
development environment (IDE) most of the time, you could see a few questions on
the exam that use the command line instead, so we're going to review the basics.
(By the way, we did NOT use an IDE while writing this book. We still have a slight
preference for the command line while studying for the exam; all IDEs do their best
to be "helpful," and sometimes they'll fix your problems without telling you. That's
nice on the job, but maybe not so great when you're studying for a certification exam!)
Compiling with javac
The javac command is used to invoke Java's compiler. You can specify many
options when running javac . For example, there are options to generate debugging
information or compiler warnings. Here's the structural overview for javac :
javac [options] [source files]
There are additional command-line options called @argfiles , but they're rarely
used, and you won't need to study them for the exam. Both the [options] and the
[source files] are optional parts of the command, and both allow multiple
entries. The following are both legal javac commands:
javac -help
javac -version Foo.java Bar.java
The first invocation doesn't compile any files, but prints a summary of valid
options. The second invocation passes the compiler an option ( -version , which
prints the version of the compiler you're using), and passes the compiler two .java
files to compile ( Foo.java and Bar.java ). Whenever you specify multiple options
and/or files, they should be separated by spaces. (Note: If you're studying for the
OCP 7, in Chapter 7 we'll talk about the assertion mechanism and when you might
use the -source option when compiling a file.)
Launching Applications with java
The java command is used to invoke the Java Virtual Machine (JVM). Here's the
basic structure of the command:
java [options] class [args]
The [options] and [args] parts of the java command are optional, and they
can both have multiple values. (Of the two exams, only the OCP 7 will use
[options] .) You must specify exactly one class file to execute, and the java
command assumes you're talking about a .class file, so you don't specify the
.class extension on the command line. Here's an example:
java -version MyClass x 1
This command can be interpreted as "Show me the version of the JVM being
used, and then launch the file named MyClass.class and send it two String
arguments whose values are x and 1 ." Let's look at the following code:
public class MyClass {
public static void main(String[] args) {
System.out.println(args[0] + " " + args[1]);
}
}
It's compiled and then invoked as follows:
java MyClass x 1
The output will be
x 1
We'll be getting into arrays in depth later, but for now it's enough to know that
args—like all arrays—uses a zero-based index. In other words, the first command line
argument is assigned to args[0] , the second argument is assigned to args[1] , and
so on.
Note: Again, for the OCP 7 candidates, in Chapter 7 we'll talk about the
assertion mechanism and when you might use flags such as -ea or -da when
launching an application.
Using public static void main(String[ ] args)
The use of the main() method is implied in most of the questions on the exam, and
on the OCA exam it is specifically covered. For the .0001% of you who don't know,
main() is the method that the JVM uses to start execution of a Java program.
First off, it's important for you to know that naming a method main() doesn't
give it the superpowers we normally associate with main(). As far as the compiler
and the JVM are concerned, the only version of main() with superpowers is the
main() with this signature:
public static void main(String[] args)
Other versions of main() with other signatures are perfectly legal, but they're
treated as normal methods. There is some flexibility in the declaration of the
"special" main() method (the one used to start a Java application): the order of its
modifiers can be altered a little, the String array doesn't have to be named args ,
and as of Java 5 it can be declared using var-args syntax. The following are all legal
declarations for the "special" main() :
static public void main(String[] args)
public static void main(String... x)
static public void main(String bang_a_gong[])
For the OCA exam, the only other thing that's important for you to know is that
main() can be overloaded. We'll cover overloading in detail in the next chapter.
Import Statements and the Java API
There are a gazillion Java classes in the world. The Java API has thousands of classes
and the Java community has written the rest. We'll go out on a limb and contend
that all Java programmers everywhere use a combination of classes they wrote and
classes that other programmers wrote. Suppose we created the following:
public class ArrayList {
public static void main(String[] args) {
System.out.println("fake ArrayList class");
}
}
This is a perfectly legal class, but as it turns out, one of the most commonly used
classes in the Java API is also named ArrayList , or so it seems.... The API
version's actual name is java.util.ArrayList . That's its fully qualified name. The
use of fully qualified names is what helps Java developers make sure that two
versions of a class like ArrayList don't get confused. So now let's say that I want to
use the ArrayList class from the API:
public class MyClass {
public static void main(String[] args) {
java.util.ArrayList<String> a =
new java.util.ArrayList<String>();
}
}
(First off, trust us on the <String> syntax; we'll get to that later.) While this is
legal, it's also a LOT of keystrokes. Since we programmers are basically lazy (there,
we said it), we like to use other people's classes a LOT, AND we hate to type. If we
had a large program, we might end up using ArrayList s many times.
import statements to the rescue! Instead of the preceding code, our class could
look like this:
import java.util.ArrayList;
public class MyClass {
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
}
}
We can interpret the import statement as saying, "In the Java API there is a
package called 'util', and in that package is a class called 'ArrayList'. Whenever you
see the word 'ArrayList' in this class, it's just shorthand for: 'java.util.ArrayList'."
(Note: Lots more on packages to come!) If you're a C programmer, you might think
that the import statement is similar to an #include . Not really. All a Java import
statement does is save you some typing. That's it.
As we just implied, a package typically has many classes. The import statement
offers yet another keystroke-saving capability. Let's say you wanted to use a few
different classes from the java.util package: ArrayList and TreeSet . You can
add a wildcard character ( * ) to your import statement that means, "If you see a
reference to a class you're not sure of, you can look through the entire package for
that class," like so:
import java.util.*;
public class MyClass {
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
TreeSet<String> t = new TreeSet<String>();
}
}
When the compiler and the JVM see this code, they'll know to look through
java.util for ArrayList and TreeSet . For the exam, the last thing you'll need to
remember about using import statements in your classes is that you're free to mix
and match. It's okay to say this:
ArrayList<String> a = new ArrayList<String>();
java.util.ArrayList<String> a2 = new java.util.ArrayList<String>();
