Ray's CSC324H Tutorial Pages


A Quick Introduction to Java Programming

Compiled by Ray Ortigas

Topics

Sources

  1. D. Flanagan, "Java in a Nutshell" (2nd edition), O’Reilly, 1997
  2. M. T. Goodrich and R. Tamassia, "Data Structures and Algorithms in Java", Wiley, 1998
  3. CSC148 Lecture Notes by Diane Horton and Faith Fich, Fall 1997
  4. CSC148 Tutorial Notes by Diane Horton, September 1998
  5. CSC108 web pages maintained by Jim Clarke

Source code

If you are using the JDK, at your command/shell prompt, enter

javac *.java

to compile the classes. Then, enter

java Example1

to run the first example or enter

java Example2

to run the second example.


What do Java classes and objects look like?

An object comes from a class, which is a specification of

In a Java class definition, the data are represented by instance variables, while the operations are represented by methods. [2]

The following is an example of a Student class. It specifies instance variables for a student's name, ID and marks. It also has two methods: one for recording a mark a student has received for a course he or she has passed, the other for getting the average mark among those courses. [4]

class Student
{
    // The student's name.
    private String name;

    // The student's ID.
    private int studentNo;

    // The student's marks. Since we're using an array, we
    // need to keep track of how many marks are in the array
    // and state how many marks can be in the array.
    private int[] marks;
    private int numMarks;
    public static final int MAX_NUMBER_OF_MARKS = 40;

    // Construct a new Student object with ID n and name s.
    public Student( int n, String s ) { /* ... */ }

    // Record the fact that the student passed a course
    // with the given mark.
    public void passCourse( int mark ) { /* ... */ }

    // Return the average mark among the courses that the
    // student passed.
    public float average() { /* ... */ }
}

(For now, ignore the public and private modifiers. We'll explain these later.)

The class also has a constructor Student() that allows programmers to create new Student objects, and in this case, initialize the objects' name and ID variables. To create an object, use the new operator in conjunction with the constructor. For example, the following line would create a Student object with an ID of '7' and a name of 'Ray', and assign to the variable ray a reference to that object:

Student ray = new Student(7, "Ray");

We haven't implemented Student's methods yet, but we could write a program that could use the class and test it! Which begs the question...

What does a Java program look like?

To run a Java program, you run a class (which may make use of many other classes). Java automatically starts by running that class' main() method, which must have the signature

public static void main(String[] args)

where args is an array of strings that gives access to any command-line arguments. [3]

The following class, Example, implements this method, and uses the Student class [4]:

class Example 
{
    public static void main (String[] args) 
    {
        Student Fred, Betty;
        Fred = new Student(12345, "Fred Flintstone");
        Fred.passCourse(75);
        Fred.passCourse(68);

        Betty = new Student(90210, "Betty Rubble");
        Betty.passCourse(92);

        System.out.println("Fred's avg: " + Fred.average() + " and " +
                           "Betty's avg: " + Betty.average());
    }
}

In this example, two Student objects are created and initialized (using the constructor Student()), and are then referenced by Fred and Betty. Their marks are recorded (using passCourse()) and their averages are printed out using the line:

System.out.println("Fred's avg: " + Fred.average() + " and " +
                   "Betty's avg: " + Betty.average());

(In general, System.out.println() is used to print to the standard output. System.out.print() does the same thing, except that it doesn't append a new line to the string.)

Since Fred's average is 71.5 and Betty's average is 92, we would expect the output to be something like:

Fred's avg: 71.5 and Betty's avg: 92.0

Let's implement our Student class so that it fulfills these (and similar) expectations [4]:

class Student
{
    // The student's name.
    private String name;

    // The student's ID.
    private int studentNo;

    // The student's marks. Since we're using an array, we
    // need to keep track of how many marks are in the array
    // and state how many marks can be in the array.
    private int[] marks;
    private int numMarks;
    public static final int MAX_NUMBER_OF_MARKS = 40;

    // Construct a new Student object with ID n and name s.
    public Student( int n, String s ) 
    {
        studentNo = n;
        name = s;
        marks = new int[MAX_NUMBER_OF_MARKS];
        numMarks = 0;
    }

    // Record the fact that the student passed a course
    // with the given mark.
    // Precondition: numMarks < MAX_NUMBER_OF_MARKS
    public void passCourse( int mark )
    { 
        marks[numMarks] = mark;
        numMarks++; 
    }

    // Return the average mark among the courses that the
    // student passed.
    public float average() 
    {
        float sum = 0;
        for (int i = 0; i < numMarks; i++)
            sum += marks[i];

        return sum / numMarks;
    }
}

It seems rather inconvenient that we have to worry about this array of marks in our implementation of the Student object. We have to take care of creating the array, recording marks in the array, making sure our count is correct and calculating the average. It would be great if we could delegate these responsibilities to another object, say ListOfMarks [4]:

class ListOfMarks
{
    // Construct a new ListOfMarks object.
    public ListOfMarks() { /* ... */ }

    // Add the mark to the list.
    public void addMark( int mark ) { /* ... */ }

    // Return the average mark.
    public float average() { /* ... */ }
}

With these changes, our Student class could be re-implemented in a much simpler fashion:

class Student
{
    // The student's name.
    private String name;

    // The student's ID.
    private int studentNo;

    // The student's marks.
    private ListOfMarks marks;

    // Construct a new Student object with ID n and name s.
    public Student( int n, String s ) 
    {
        studentNo = n;
        name = s;
        marks = new ListOfMarks();
    }

    // Record the fact that the student passed a course
    // with the given mark.
    public void passCourse( int mark )
    { 
        marks.addMark(mark);
    }

    // Return the average mark among the courses that the
    // student passed.
    public float average() 
    {
        return marks.average();
    }
}

Meanwhile, the ListOfMarks class can use most of the code that was formerly in Student [4]:

class ListOfMarks 
{
    private int [] marks;
    private int numMarks;

    // The maximum number of marks this list can have.
    public static final int MAX_NUMBER_OF_MARKS = 40;

    // Construct a new ListOfMarks object.
    public ListOfMarks() 
    {
        marks = new int[MAX_NUMBER_OF_MARKS];
        numMarks = 0;
    }

    // Add the mark to the list.
    // Precondition: numMarks < MAX_NUMBER_OF_MARKS
    public void addMark( int mark ) 
    {
        marks[numMarks] = mark;
        numMarks++;
    }

    // Return the average mark.
    public float average () 
    {
        float sum = 0;
        for (int i = 0; i < numMarks; i++)
            sum += marks[i];
        
        return sum / numMarks;
    }
}

Things seem better organized now, don't they!

Now try designing a Course class that represents a university course and allows you to

If you use the ListOfMarks class, this is really easy! Try writing the class, and then compare your answer to this solution. Click here for an example that uses the Course class.

Hopefully you have recognized a benefit of breaking things down into smaller pieces: If one of those smaller pieces is useful enough, you can reuse it in other code that you write and save time. You could even generalize the ListOfMarks class further into a ListOfInts class which keeps around a list of integers. The implementation is pretty much the same.

Now that you have an idea of what Java programs look like, here are some answers to a couple more questions you might be asking.

How do I read input into my program?

Input from the keyboard goes into System.in, the standard input stream. So you have to create an object that will read from that stream. This can be done with the following line:

BufferedReader stdin = new BufferedReader (new InputStreamReader (System.in));

To read in a line and store it in a String object, you can use this line:

String inputLine = stdin.readLine();

Here is a simple program that reads a line from the standard input and prints it out:

import java.io.*;

public class InputExample
{
    public static void main(String[] args) throws IOException
    {
	BufferedReader stdin = new BufferedReader (new InputStreamReader (System.in));
	String inputLine = stdin.readLine();
	System.out.println("You typed: " + inputLine);
    }
}

There are three more things to note:

For more information...

What is the Java API?

The Java Application Programming Interface (API) is an extensive library of software components. It defines lots of useful stuff so you don't have to. [3]

The API is organized into various packages. When you first start, the ones you most likely will encounter are:

You've probably also heard of the Abstract Window Toolkit (AWT), which defines pull-down menus, tick-boxes, etc. that make it easy to create graphical user interfaces (GUIs). [3] This can be found in java.awt.

For more information...


Main CSC324H Home Page | Ray's CSC324H Home Page

This page is maintained by Ray Ortigas, a teaching assistant for CSC324H - Principles of Programming Languages at the Department of Computer Science, University of Toronto. If you have any questions or comments about this page, please send e-mail to Ray at rayo@cs.toronto.edu.

Last updated March 21, 1999 18:04.