The problem has not changed in that it still deals with the same geometric shape, a rectangle, described in terms of the same dimensions, its width and height. What vary are simply the values of the width and the height. The formula to compute the area of a rectangle given its width and height does not change:

width * height

It does not care what the actual specific values of width and height are. What it cares about is that the values of width and height must be such that the multiplication operation makes sense. How do we express the above invariants in Java?

We just want to think of the width and height of a given rectangle as elements of the set of real numbers. In computing, we group values with common characteristics into a set and called it a
**type**. In Java, the type **double** is the set of real numbers that are implemented inside the computer in some specific way. The details
of this internal representation is immaterial for our purpose and thus can be ignored. In addition to the type double, Java provides many more pre-built types such as **int** to represent the set of integers and **char** to represent the set of characters. We will examine and use them as their need arises in future
examples. As to our problem, we only need to restrict ourselves to the type double.

We can define the width and the height of a rectangle as double in Java as follows.

double width;double height;

The above two statements are called **variable** definitions where width and height are said to be variable names. In Java, a variable represents a memory location
inside the computer. We define a variable by first declare its type, then follow the type by the name of the variable, and terminate the definition with a semi-colon. This a Java syntax rule.
Violating a syntax rule constitutes an error. When we define a variable in this manner, its associated memory content is initialized to a default value specified by the Java language. For
variables of type double, the default value is 0.

Once we have defined the width and height variables, we can solve our problem by writing the expression that computes the area of the associated rectangle in terms of width and height as follows.

width * height

Observe that the two variable definitions together with the expression to compute the area presented in the above directly translate the description of the problem -two real numbers
representing the width and the height of a rectangle-and the high-level thinking of what the solution of the problem should be -area is the width times the height. We have just expressed the
invariants of the problem and its solution. Now, how do we vary width and height in Java? We use what is called the **assignment** operation. To assign the value 4.5
to the variable width and the value 7.2 to the variable height, we write the following Java assignment statements.

width = 4.5;height = 7.2;

The syntax rule for the assignment statement in Java is: first write the name of the variable, then follow it by the equal sign, then follow the equal sign by a Java expression, and terminate
it with a semi-colon. The semantic (i.e. meaning) of such an assignment is: evaluate the expression on the right hand side of the equal sign and assign the resulting value into the memory
location represented by the variable name on the left hand side of the equal side. It is an error if the type of the expression on the right hand side is not **a
subset** of the type of the variable on the left hand side.

Now if we evaluate `width * height` again (using the Interactions Window of DrJava), we should get the desired answer. Life is good so far, though there is a little
bit of inconvenience here: we have to type the expression `width * height` each time we are asked to compute the area of a rectangle with a given width and a given
height. This may be OK for such a simple formula, but what if the formula is something much more complex, like computing the length of the diagonal of a rectangle? Re-typing the formula each
time is quite an error-prone process. Is there a way to have the computer memorize the formula and perform the computation behind the scene so that we do not have to memorize it and rewrite it
ourselves? The answer is yes, and it takes a little bit more work to achieve this goal in Java.

What we would like to do is to build the equivalent of a black box that takes in as inputs two real numbers (recall type **double**) with a button. When we put in two
numbers and depress the button, "magically" the black box will compute the product of the two input numbers and spit out the result, which we will interpret as the area of a rectangle whose
width and height are given by the two input numbers. This black box is in essence a specialized calculator that can only compute one thing: the area of a rectangle given a width and a height.
To build this box in Java, we use a construct called a class, which looks like the following.

class AreaCalc {double rectangle(double width, double height) {return width * height;}}

What this Java code means is something like: `AreaCalc` is a **blue print** of a specialized computing machine that is capable of
accepting two input `doubles`, one labeled width and the other labeled height, computing their product and returning the result. This computation is given a name:
`rectangle`. In Java parlance, it is called a **method** for the class `AreaCalc`.

Here is an example of how we use `AreaCalc` to compute area of a rectangle of width 4.5 and height 7.2. In the Interactions pane of DrJava, enter the following
lines of code.

AreaCalc calc = new AreaCalc();calc.rectangle(4.5, 7.2)

The first line of code defines `calc` as a variable of type `AreaCalc` and assign to it an **instance** of
the class `AreaCalc`. **new** is a keyword in Java. It is an example of what is called a class operator. It operates on a class and
creates an instance (also called **object**) of the given class. The second line of code is a call to the object `calc` to perform the
`rectangle` task where `width` is assigned the value 4.5 and `height` is assigned the value 7.2. To get
the area of a 5.6 by 8.4 rectangle, we simply use the same calculator calc again:

calc.rectangle(5.6, 8.4);

So instead of solving just one proble -given a rectangle 4.5 ft wide and 7.2 ft high, compute its area-we havebuilt a "machine" that can compute the area of **any**
given rectangle. But what about computing the area of a right triangle with height 5 and base 4? We cannot simply use this calculator. We need another specialized calculator, the kind that can
compute the area of a circle.

There are at least two different designs for such a calculator.

- create a new class called AreaCalc2 with one method called
**rightTriangle**with two input parame tersof type**double**. This corresponds to designing a different area calculator with one button labeled**rightTriangle**with two input slots. - add to AreaCalc a method called rightTriangle with two input parameters of type
**double**. This corresponds to designing an area calculator with two buttons: one labeled**rectangle**with two input slots and the other labeled**rightTriangle**, also with two input slots.

In either design, it is the responsibility of the calculator user to pick the appropriate calculator or press the appropriate button on the calculator to correctly obtain the area of the given
geometric shape. Since the two computations require exactly the same number of input parameters of exactly the same type, the calculator user must be careful not get mixed up. This may not be
too much of an inconvenience if there are only two kinds of shape to choose from: rectangle and right triangle. But what if the user has to choose from hundreds of different shapes? or better
yet an **open-ende** number of shapes? How can we, as programmers, buid a calculator that can handle an **infinite** number of shapes? The
answer lies in **abstraction**. To motivate how conceptualize the problem, let us digress and contemplate the behavior of a child!

- 500 reads