Algorithms and OOD (CSC 207 2014F) : Readings
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] - [Learning Outcomes] [FAQ] [Teaching & Learning] [Grading] [Rubric] - [Calendar]
Current: [Assignment] [EBoard] [Lab] [Outline] [Reading]
Sections: [Assignments] [EBoards] [Examples] [Handouts] [Labs] [Outlines] [Readings]
Reference: [Student-Curated Resources] [Java 8 API] [Java 8 Tutorials] [Code Conventions]
Related Courses: [CSC 152 2006S (Rebelsky)] [CSC 207 2014S (Rebelsky)] [CSC 207 2014F (Walker)] [CSC 207 2011S (Weinman)]
Misc: [Submit Questions] - [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] - [Issue Tracker (Course)] [Issue Tracker (Textbook)]
Summary: We give a quick tour through some imperative parts of Java and how they relate to what you may know from learning the C programming language.
Java is a hybrid language. While it has significant object-oriented features, it also has many imperative features. That is, while you will be building objects and taking advantage of encapsulation, polymorphism, and inheritance, you will also write programs in which you sequence instructions and update state through assignment. You may note that Java looks a lot like C. That's intentional. The designers of Java thought they would attract more programmers if they started with a familiar basis.
If you're willing to ignore the object-oriented features and to
put up with a bit more stuff to type, Java can be a reasonable
alternative to C for imperative programming. Why is it better?
You still have some opportunity for information hiding, and it
is much stricter about types, which helps you catch errors
earlier. For example, Java distinguishes Boolean values from integers,
and won't let you use one for the other. (Yes, that's right, the
Java compiler won't let you write the incorrect “while
(i = 0)” rather than the intended “while
(i == 0)”
main Method
Java requires that all of your code reside in classes.
While classes are primarily intended as templates for making objects,
they also gather together related functions and variables. Hence,
even if all you want is a main method, you will need
to create a class to hold it.
public class MyClass
{
public static void main(String[] args)
throws Exception
{
...
} // main(String[])
} // MyClass
As you probably noted, the “signature” of
main is a bit different in Java than it is
in C. As in C, Java's main takes an array
of strings as parameters. But Java uses the String type
(or, more formally, java.lang.String) rather than C's
char *. In addition, in Java you can find out the length
of any array, so we don't need to take the length as a parameter.
Since Java is designed, in part, to allow the programmer to protect
pieces of code from other pieces of code (that's part of encapsulation),
you almost always declare the protection level of a method. If you
don't, Java has a default protection level of “this method may
be called by any other method in the same package”, which I will
refer to as “package protection”. Since the operating
system will be starting our program by calling the
main method, we must make
main public.
Java distinguishes between methods that are associated with the objects
in a class and the methods that are associated with the class as a
whole. The designers of Java chose the keyword static
to indicate that a method (or field) is associated with the class
rather than with individual objects. (The name is somewhat sensible -
objects live in dynamic memory, but static methods can live in static
memory.)
In C, the return type of main is
int. That's because C returns information about
success or failure using that integer. (If you recall, in this
case, 0 means “success” and anything else represents
some sort of error.) In Java, a program signals error in a different
way, and so there is no need to return a value. Hence, the
return type is void.
Finally, that bit of code that says throws Exception is
our way of signaling that the program can fail. You'll learn about
throwing exceptions later.
Programmers have strong opinions on how code should be formatted. Such conventions dictate everything from capitalization and naming of variables to indentation and placement of braces and parens. While there are a variety of conventions in Java, almost all of them share the following capitalization choices.
Java, like C, has basic numeric types, including int,
short, long, float, and
double. Unlike C, Java carefully specifies what
representation and ranges are used for each of these. (You can
find those specifications online if you look carefully.)
Java also has the void type (nothing), and
the char type (Unicode characters, I believe).
Java does not have pointers. (It has references, but it does not
let you reference and dereference like you can in C; it does not let
you get an address.) Java's strings are therefore their own type,
String or java.lang.String.
Java also provides a boolean type for truth values,
along with values true and false.
As you've seen in the case of main, basic
functions (well, methods) in Java require three pieces of additional
information in addition to the method name, return type, and
parameter list you used in C.
public (accessible anywhere) and
nothing (accessible only via the package), you can make
methods private (only accessible from within the
class) and protected (only within the package and
in subclasses).
static specification. Until you start
creating you own template classes, you'll need to make
all of your
methods static.
throws clause to indicate possible errors.
Until we cover throwing and catching exceptions, you will find it
easiest to indicate that any method you write throws an exception.
For example,
/**
* Compute the square of x.
*
* @exception Exception
* when the square is larger than the largest int.
*/
public static int square (int x)
throws Exception
As you may recall, in C there are two primary kinds of variables: global variables, which are available to any procedure in your program, and local variables, which are only available within your procedure.
You will find that local variables in Java are much like local variables in C. That is, you declare them by giving the type and the name of the variable.
long result;
Global variables are a bit more complex. Once again, you declare them
by giving the type and name. But you can also add a protection level
like those you use for methods - public, protected,
nothing (“package”), or private.
/** * A count of the number of errors encountered during testing. */ private int errorCount = 0;
Java provides if-then-else and switch statements that essentially mimic C's statements.
Java provides while loops, do-while loops, and for loops that look much like what you've seen in C. One big difference with these loops is that you can declare variables in the loop header. Hence, while C programmers declare their counter variables in one place and then use them elsewhere, in Java, programmers tend to write things like the following:
for (int i = 0; i < MAX_VALUE; i++)
C99 programmers also write for loops that put the declaration in the loop header. But many (most?) C programmers stick to an earlier version of C and leave the declaration outside of the foor loop.
Java also provides s special loop that makes it much easier to access every element in a list or array. (More formally, to access every element in a collection that supports iteration.)
for (s : args) ...
The one initial change you'll see in your programming is a tendency to declare variables within the initialization segments of a for loop.
In C, you import library code by using #include to tell
the compiler about the specifications for that code and then linking
to that library code.
In Java, you just mention the library code and the compiler automatically
figures out how to bring it in. Traditionally, you give the full
name of the library, such as java.io.PrintWriter.
Suppose Util.java was declared as follows.
package edu.grinnell.csc207.utils;
public class MathUtils
{
public static int square(int x)
throws Exception
{
...
} // square(int)
} // class MathUtils
To call square, you would write
edu.grinnell.csc207.utils.MathUtils.square(...)
Note that for some library code, particularly using standard libraries,
you'll need to create objects. For example, to use a
PrintWriter, I need to write
java.io.PrintWriter pen = new java.io.PrintWriter(System.out,true);
But that's a lot of extra work. Hence, Java also lets you
“import” classes using the import keyword.
If you've imported classes, you need only provide their base name,
and not the full qualification.
import edu.grinnell.csc207.utils.MathUtils; import java.io.PrintWriter; MathUtils.square(...) PrintWriter pen = new PrintWriter(System.out, true);
Java provides a host of input and output mechanisms. I prefer that you use the object-oriented ones.
To print output, first create an object of class
java.io.PrintWriter.
java.io.PrintWriter pen = new java.io.PrintWriter(System.out,true);
You can then print using that object's print and
println methods. (There's also a printf
method that works much like C's printf.) You may
also find it useful to use the flush method and to
close the PrintWriter when you are done with it.
pen.println("Hello");
For input, you probably want to use a java.io.BufferedReader,
which you typically create with something like:
java.io.BufferedReader eyes =
new java.io.BufferedReader(new java.io.InputStreamReader (System.in));
You can then use the readLine method to read
input.
We'll consider arrays at a later time.