[an error occurred while processing this directive] [an error occurred while processing this directive] Object-Oriented Programming in Java
Rice University
COMP 200
Elements of Computer Science
Fall 2005
Object-Oriented Programming in Java


DrJava

DrJava is a pedagogical programming environment developed by the Programming Languages Technology group at Rice University designed to teach object-oriented programming in Java.

To run DrJava, we need to have what is called the "Java SDK 1.5" installed. Rice IT staff already installed such program on the computers in the Symonds 2 and many other PC labs on campus.

To download the Java SDK 1.5, go to the following web site:

http://java.sun.com/j2se/1.5.0/download.jsp

Follow the instructions there to download and install the SDK on your computer.

NOTE: You need to install the SDK BEFORE installing DrJava so that DrJava can find the SDK and initializes itself properly.

To check if your computer has such program, open a console window and type in the command:

> java -version.

You should see something like

java version "1.5.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
Java HotSpot(TM) Client VM (build 1.5.0_02-b09, mixed mode, sharing)

With such a JDK installed on your computer, you can run DrJava by simply double-click on the DrJava icon.

Let's explore DrJava by going back to the problem of converting temperature from Celsius to Fahrenheit described in Lecture 4.

The Problem of Temperature Conversion

DrJava Solution 1

We can use our favorite tool DrJava and enter the formula F = 9/5 *C + 32 with C replaced by 15, as shown below.

Welcome to DrJava.
> 9/5 * 15 + 32
47
>

Note that, unlike Scheme that uses the prefix notation for all of its expressions, Java uses the infix notation. 

As we enter the expression 9/5 * 15 + 32 in the Interactions Pane and hit Enter, DrJava immediately displays the result: 47. Is that what we expected? No, 9/5 * 15 + 32 should be 59. Our program didn't work, or more correctly: it didn't do what we had in mind. What happened?

Java treats the numbers differently from what we expect.  It uses integer arithmetic to perform this calculation, i.e. Java uses only whole numbers, and drops any decimal digits after each step of the calculation. Therefore, 9/5 is computed as just 1, not 1.8.

A computer only has a limited amount of memory, and therefore, numbers cannot always be represented exactly. Sometimes, the programmer has to make a compromise between memory usage and precision. Using integers instead of floating-point numbers, which can have decimals, is one of those compromises.

If Java sees a number that doesn't have to be a floating-point number, it will treat it as an integer.

All the numbers in our formula are whole numbers, so Java treats all of them as integers; therefore, integer arithmetic is used in the entire calculation. 9/5 * 15 + 32 evaluates to 1 * 15 + 32, which evaluates to 15 + 32, which results in 47.

We can force Java to treat them as floating-point numbers by appending a .0 to each number. Let's try our formula again:

Welcome to DrJava.
> 9.0/5.0 * 15.0 + 32.0
59.0
>

After we press Enter this time, DrJava displays 59.0.  This time, Java did what we expected: The above is a program that solves the stated problem.  It is an example of what is called a "constant" program. 

What is good about this program is that it is simple, easy to understand, and most importantly it correctly solves the original problem.  However, if we change slightly the problem to converting 17o Celsius to Fahrenheit, the program no longer is applicable.  Intuitively, the problem has not really changed at all: the "real" problem is about converting a temperature measurement in Celsius to the corresponding value in Fahrenheit. 

What has changed is the value of the temperature measurement.  The mathematical formula expressing the conversion process is an invariant: it does not change.  The value of the variable C is a variant: something that can change arbitrarily.  The above constant program fails to capture the variant/invariant nature of the mathematical formula, and as a result, cannot be used to solve the same conversion problem with a different temperature measurement.

What we want to do is to write a program that has an invariant part that corresponds to the formula and a variant part that allows entering arbitrary values for C.

DrJava Solution 2

We redesign our Java solution and enter the following:

Welcome to DrJava.
> class CelsiusToFahrenheit {
    double convert(double celsius) {
        return 9.0/5.0 * celsius + 32.0;
    }
}
>

The middle three lines beginning with double convert(double C) { and ending with the first } define a function or method, as Java calls it. Mathematically, a function is a mapping of one set of values, called the domain, to another set of values, called the range.  In our example, we are taking temperatures in Celsius and mapping them to temperatures in Fahrenheit, i.e. the domain is temperatures in Celsius, and the range is temperatures in Fahrenheit.

What is a class?

Java is an object-oriented language, though, and that means every function exists in some context.  This context is called a class and may contain other methods and fields that store data.  Additional methods or fields are not necessary here, but we still have to put the convert method inside a class.  In our example, we called the class CelsiusToFahrenheit.

Class syntax

Classes definitions begin with the Java keyword class, followed by the name of the class and a pair of opening and closing braces { }.  Methods are defined by first specifying the type of the return value (double here, meaning floating-point values), then giving the method a name (this method is called convert), and then listing the method parameters inside a pair of parentheses ( ). The list method parameters consists of type-name pairs. convert only has one parameter whose type is double and whose name is celsius. Method parameters work as "input" of a function, while the return value works as the "output".  After the closing parenthesis, a pair of braces { } encloses the method body, which describes the actions the method should perform.  In this example, we want to return the result of the computation 9.0/5.0 * celsius + 32.0.

What is an Object?

Now we have defined a class with a method that can perform the required calculation.  We have not actually used it, though.  To do that, we enter the following lines of code into the DrJava Interactions Pane:

> CelsiusToFahrenheit CtoF = new CelsiusToFahrenheit();
> CtoF.convert(15.0)
59.0
>

The first of these lines creates a new object of the class CelsiusToFahrenheit.  This object has the name CtoF.   You can think of the class as a blueprint of an airplane; it describes all the details of the airplane, but it is not an airplane itself.  The object is an instance of what is described in the blueprint; it is the real, tangible thing.  The second line then invokes the convert method of the CtoF object; it asks the object to perform the computation described in the method definition. The temperature in Celsius, 15.0 here, is provided as argument to the method.  Whatever value we provide as argument when we use a method becomes the value of the parameter inside the method body.  When we press return after the second line, DrJava immediately displays the result of that computation: 59.0.

In this solution, the user can enter any value for the temperature in Celsius as the argument to the convert method and press Enter, and DrJava will immediately compute the corresponding temperature in Fahrenheit.  The formula encoded in the method refers to the value of the parameter celsius for the temperature.  The number given as argument may change, it is variant; the formula in the method is always the same, it is invariant.  Therefore, this solution captures the mathematical formula more faithfully.

However, our program still cannot do very much.  We can convert all temperatures measured in Celsius to their corresponding temperatures in Fahrenheit, but that is all we can do. We cannot even convert Fahrenheit temperatures back to Celsius, even though the equation

F = 9/5 *C + 32

expresses the entire relation between Fahrenheit and Celsius.  Using our knowledge of algebra, we can solve this equation for the variable C and get:

C = 5/9 * (F - 32)

DrJava Solution 3

We can now use this information to write another class that provides two methods, so it can do both conversions:

Welcome to DrJava.
> class TemperatureConverter {
    double convertCtoF(double celsius) {
        return 9.0/5.0 * celsius + 32.0;
    }
    double convertFtoC(double fahrenheit) {
        return 5.0/9.0 * (celsius - 32.0);
    }
}
> TemperatureConverter converter = new TemperatureConverter();
> converter.convertCtoF(15.0)
59.0
> converter.convertFtoC(59.0)
15.0

We now have a program that can convert temperatures back and forth between the Celsius and the Fahrenheit scale. The pattern to extend this should be clear: For each conversion, we add another method to the TemperatureConverter class.

There is a problem, though: To keep the TemperatureConverter class general enough to convert from any scale to any other scale, we have to add more and more methods. If we add the Kelvin scale, we have to write methods to convert from Kelvin to Celsius and back, and from Kelvin to Fahrenheit and back -- four new methods. If we then throw the Réaumur scale in the mix, we have to add Réaumur to Celsius and back, Réaumur to Fahrenheit and back, and Réaumur to Kelvin and back -- six new methods. Adding another scale would require eight new methods, and so on. This approach clearly does not scale well, i.e. a small change in one place necessitates a large change somewhere else. Here, in order to maintain the program's generality, adding one temperature scale requires us to add many conversion methods.

Is there a solution that scales better, a design in which adding a temperature scale only requires a constant amount of work, not ever more and more?


© Dung X. Nguyen

Last revised 11/28/2005 09:48 AM

Maintained by the professor; see contact information on the course home page