Chapter 17

Programming with Objects and Classes

IN THIS CHAPTER

check Programming with class (and with style and finesse)

check Making objects from classes

check Joining the exclusive “I understand classes and objects” society

Chapters 6, 7, and 8 introduce Java’s primitive types — things like int, double, char, and boolean. That’s great, but how often does a real-world problem deal exclusively with such simple values? Consider an exchange between a merchant and a customer. The customer makes a purchase, which can involve item names, model numbers, credit card info, sales tax rates, and lots of other stuff. A purchase is more complicated than an int value. It’s more complicated than a double value. How do you represent an entire purchase in a Java program?

In older computer programming languages, you treat an entire purchase like a big pile of unbundled laundry. Imagine a mound of socks, shirts, and other pieces of clothing. You have no basket, so you grab as much as you can handle. As you walk to the washer, you drop a few things — a sock here and a washcloth there. This is like the older way of storing the values in a purchase. In older languages, there’s no purchase. There are only double values, char values, and other loose items. You put the purchase amount in one variable, the customer’s name in another, and the sales tax data somewhere else. But that’s awful. You tend to drop things on your way to the compiler. With small errors in a program, you can easily drop an amount here and a customer’s name there.

With laundry and computer programming, you’re better off if you have a basket. The newer programming languages, like Java, allow you to combine values and make new, more useful kinds of values. For example, in Java, you can combine a double value, an int value, a boolean value, and maybe other kinds of values to create something that you call a Purchase. Because your purchase info is all in one big bundle, keeping track of the purchase’s pieces is easier. That’s the start of an important computer programming concept: the notion of object-oriented programming.

Creating a Class

I start with a “traditional” example. The program in Listing 17-1 processes simple purchase data. A run of the program is shown in Figure 17-1.

image

FIGURE 17-1: Processing a customer’s purchase.

LISTING 17-1 Doing It the Old-Fashioned Way

import java.util.Scanner;

class ProcessData {

public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
double unitPrice;
int quantity;
boolean taxable;

System.out.print("Unit price: ");
unitPrice = keyboard.nextDouble();
System.out.print("Quantity: ");
quantity = keyboard.nextInt();
System.out.print("Taxable? (true/false) ");
taxable = keyboard.nextBoolean();

double total = unitPrice * quantity;
if (taxable) {
total = total * 1.05;
}

System.out.print("Total: ");
System.out.println(total);

keyboard.close();
}
}

If the output in Figure 17-1 looks funny, it’s because I do nothing in the code to control the number of digits beyond the decimal point. So in the output, the value $42.00 looks like 42.0. That’s okay. I show you how to fix the problem in Chapter 18.

Reference types and Java classes

The code in Listing 17-1 involves a few simple values: unitPrice, quantity, and taxable. So here’s the main point of this chapter: By combining several simple values, you can get a single, more useful value. That’s the way it works. You take some of Java’s primitive types, whip them together to make a primitive type stew, and what do you get? You get a more useful type called a reference type. Listing 17-2 has an example.

LISTING 17-2 What It Means to Be a Purchase

class Purchase {
double unitPrice;
int quantity;
boolean taxable;
}

The code in Listing 17-2 has no main method, so Eclipse can compile the code, but you can’t run it. When you choose Run ⇒   Run As on Eclipse’s main menu, the resulting context menu has no Java Application entry. You can click the tiny Run As button in Eclipse’s toolbar and then select Java Application. But then you get the message box shown in Figure 17-2. Because Listing 17-2 has no main method, there’s no place to start the executing. (In fact, the code in Listing 17-2 has no statements at all. There’s nothing to execute.)

image

FIGURE 17-2: The code in Listing 17-2 has no main method.

Using a newly defined class

To do something useful with the code in Listing 17-2, you need a main method. You can put the main method in a separate file. Listing 17-3 shows you such a file.

LISTING 17-3 Using Your Purchase Class

import java.util.Scanner;

class ProcessPurchase {

public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
Purchase onePurchase = new Purchase();

System.out.print("Unit price: ");
onePurchase.unitPrice = keyboard.nextDouble();
System.out.print("Quantity: ");
onePurchase.quantity = keyboard.nextInt();
System.out.print("Taxable? (true/false) ");
onePurchase.taxable = keyboard.nextBoolean();

double total = onePurchase.unitPrice * onePurchase.quantity;
if (onePurchase.taxable) {
total = total * 1.05;
}

System.out.print("Total: ");
System.out.println(total);

keyboard.close();
}
}

The best way to understand the code in Listing 17-3 is to compare it, line by line, with the code in Listing 17-1. In fact, there’s a mechanical formula for turning the code in Listing 17-1 into the code in Listing 17-3. Table 17-1 describes the formula.

TABLE 17-1 Converting Your Code to Use a Class

In Listing 17-1

In Listing 17-3

double unitPrice;

int quantity

boolean taxable;

Purchase onePurchase = new Purchase();

unitPrice

onePurchase.unitPrice

quantity

onePurchase.quantity

taxable

onePurchase.taxable

The two programs (in Listings 17-1 and 17-3) do essentially the same thing, but one uses primitive variables, and the other leans on the Purchase code from Listing 17-2. Both programs have runs like the one shown back in Figure 17-1.

Running code that straddles two separate files

From Eclipse’s point of view, a project that contains two Java source files is no big deal. You create two classes in the same project, and then you choose Run ⇒   Run As ⇒   Java Application. Everything works the way you expect it to work.

The only time things become tricky is when you have two main methods in the one project. This section’s example (refer to Listings 17-2 and 17-3) doesn’t suffer from that malady. But as you experiment with your code, you can easily add classes with additional main methods. You may also create a large application with several starting points.

When a project has more than one main method, Eclipse may prompt you and ask which class’s main method you want to run. But sometimes Eclipse doesn’t prompt you. Instead, Eclipse arbitrarily picks one main method and ignores all the others. This can be very confusing. You add a println call to the wrong main method, and nothing appears in the Console view. Hey, what gives?

You can fix the problem by following these steps:

  1. Expand the project’s branch in the Package Explorer.
  2. Expand the src folder within the project’s branch.
  3. Expand the (default package) branch within the src branch.

    The (default package) branch contains .java files.

  4. (In Windows) Right-click the .java file whose main method you want to run. (On a Mac) Control-click the .java file whose main method you want to run.
  5. On the resulting context menu, choose Run As ⇒   Java Application.

remember You cannot run a project that has no main method. If you try, you get a message box like the one shown earlier, in Figure 17-2.

Why bother?

On the surface, the code in Listing 17-3 is longer, more complicated, and harder to read. But think about a big pile of laundry: It may take time to find a basket and to shovel socks into the basket, but when you have clothes in the basket, the clothes are much easier to carry. It’s the same way with the code in Listing 17-3. When you have your data in a Purchase basket, it’s much easier to do complicated things with purchases.

From Classes Come Objects

The code in Listing 17-2 defines a class. A class is a design plan; it describes the way in which you intend to combine and use pieces of data. For example, the code in Listing 17-2 announces your intention to combine double, int, and boolean values to make new Purchase values.

Classes are central to all Java programming. But Java is called an object-oriented language. Java isn’t called a class-oriented language. In fact, no one uses the term class-oriented language. Why not?

Well, you can’t put your arms around a class. A class isn’t real. A class without an object is like a day without chocolate. If you’re sitting in a room right now, glance at all the chairs in the room. How many chairs are in the room? Two? Five? Twenty? In a room with five chairs, you have five chair objects. Each chair (each object) is something real, something you can use, something you can sit on.

A language like Java has classes and objects. What’s the difference between a class and an object?

  • An object is a thing.
  • A class is a design plan for things of that kind.

For example, how would you describe what a chair is? Well, a chair has a seat, a back, and legs. In Java, you may write the stuff in Listing 17-4.

LISTING 17-4 What It Means to Be a Chair

/*
* This is real Java code, but this code
* cannot be compiled on its own:
*/

class Chair {
FlatHorizonalPanel seat;
FlatVerticalPanel back;
LongSkinnyVerticalRods legs;
}

The code in Listing 17-4 is a design plan for chairs. The code tells you that each chair has three things. The code names the things (seat, back, and legs) and tells you a little bit about each thing. (For example, a seat is a FlatHorizontalPanel.) In the same way, the code in Listing 17-2 tells you that each purchase has three things. The code names the things (unitPrice, quantity, and taxable) and tells you the primitive type of each thing.

Imagine some grand factory at the edge of the universe. While you sleep each night, this factory stamps out tangible objects — objects that you’ll encounter during the next waking day. Tomorrow you’ll go for an interview at the Sloshy Shoes Company. So tonight the factory builds chairs for the company’s offices. The factory builds chair objects, as shown in Figure 17-3, from the almost-real code in Listing 17-4.

image

FIGURE 17-3: Chair objects from the Chair class.

In Listing 17-3, the line

Purchase onePurchase = new Purchase();

behaves like that grand factory at the edge of the universe. Rather than create chair objects, that line in Listing 17-3 creates a Purchase object, as shown in Figure 17-4. That particular line in Listing 17-3 is a declaration with an initialization. Just as the line

int count = 0;

declares the count variable and sets count to 0, the line in Listing 17-3 declares the onePurchase variable and makes onePurchase point to a brand-new object. That new object contains three parts: an unitPrice part, a quantity part, and a taxable part.

image

FIGURE 17-4: An object created from the Purchase class.

technicalstuff If you want to be picky, there’s a difference between the stuff in Figure 17-4 and the action of the statement Purchase onePurchase = new Purchase() from Listing 17-3. Figure 17-4 shows an object with the values 20.00, 2, and true stored in it. The statement Purchase onePurchase = new Purchase() creates a new object, but it doesn’t fill the object with useful values. Getting values comes later in Listing 17-3.

Understanding (or ignoring) the subtleties

Sometimes, when you refer to a particular object, you want to emphasize which class the object came from. Well, subtle differences in emphasis call for big differences in terminology. So here’s how Java programmers use the terminology:

  • In Listing 17-3, the statement Purchase onePurchase = new Purchase() creates a new object.
  • In Listing 17-3, the statement Purchase onePurchase = new Purchase() creates a new instance of the Purchase class.

The words object and instance are almost synonymous, but Java programmers never say “object of the Purchase class” (or if they do, they feel funny).

By the way, if you mess up this terminology and say something like “object of the Purchase class,” no one jumps down your throat. Everyone understands what you mean, and life goes on as usual. In fact, I often use a phrase like “Purchase object” to describe an instance of the Purchase class. The difference between object and instance isn’t terribly important. But it’s important to remember that the words object and instance have the same meaning. (Okay! They have nearly the same meaning.)

Making reference to an object’s parts

In the Purchase code of Listing 17-2, I declare three variables: a unitPrice variable, a quantity variable, and a taxable variable. In real-life, you might say that each purchase has three parts: the unitPrice of an item being purchased, the quantity of items purchased, and the fact that the purchase is or isn’t taxable.

When you create a Java class, each of these variables is called a field. The Purchase class has three fields — namely, the unitPrice field, the quantity field, and the taxable field.

After you’ve created an object, you use dots to refer to the object’s fields. For example, in Listing 17-3, I put a value into the onePurchase object’s unitPrice field with the following code:

onePurchase.unitPrice = keyboard.nextDouble();

Later in Listing 17-3, I get the unitPrice field’s value with the following code:

double total = onePurchase.unitPrice * onePurchase.quantity;

This dot business may look cumbersome, but it really helps programmers when they’re trying to organize the code. In Listing 17-1, each variable is a separate entity. But in Listing 17-3, each use of the word unitPrice is inextricably linked to the notion of a purchase. That’s good.

technicalstuff Every field is a variable, but not every variable is a field. For example, in the following code, the amount variable isn’t a field because it’s declared inside of the main method.

public static void main(String args[]) {
double amount;
amount = 5.95;
// … Etc.

One way or another, I don’t want you to get bogged down thinking about the words field and variable. A field is simply a variable that has a special role inside of a class. When I want to emphasize that special role, I use the word field. When I don’t want to emphasize that special role, I use the word variable. I may even switch back and forth between field and variable in the same sentence. Who knows? I might call something a fariable or a vield.

If you care about which word I use and when I use it, good for you. If you don’t care, don’t worry about it.

Creating several objects

After you’ve created a Purchase class, you can create as many purchase objects as you want. For example, in Listing 17-5, I create two purchase objects.

LISTING 17-5 Processing Purchases

class ProcessPurchases {

public static void main(String[] args) {
Purchase purchase1 = new Purchase();
purchase1.unitPrice = 20.00;
purchase1.quantity = 3;
purchase1.taxable = true;

Purchase purchase2 = new Purchase();
purchase2.unitPrice = 20.00;
purchase2.quantity = 3;
purchase2.taxable = false;

double purchase1Total = purchase1.unitPrice * purchase1.quantity;
if (purchase1.taxable) {
purchase1Total *= 1.05;
}

double purchase2Total = purchase2.unitPrice * purchase2.quantity;
if (purchase2.taxable) {
purchase2Total *= 1.05;
}

if (purchase1Total == purchase2Total) {
System.out.println("No difference");
} else {
System.out.println("These purchases have different totals.");
}
}
}

Figure 17-5 has a run of the code in Listing 17-5, and Figure 17-6 illustrates the concept.

image

FIGURE 17-5: Running the code in Listing 17-5.

image

FIGURE 17-6: From one class come two objects.

remember To compile the code in Listing 17-5, you must have a copy of the Purchase class in the same project. (The Purchase class is in Listing 17-2.) To copy a class’s code from one project to another, see Chapter 16. (That chapter’s sidebar, “Grabbing input here and there,” describes the copy-and-paste routine.)

Listing 17-5 has two purchase objects because the code

new Purchase();

is executed two times.

tip Just as you can separate an int variable’s assignment from the variable’s declaration

int count;
count = 0;

you can also separate a Purchase variable’s assignment from the variable’s declaration:

Purchase purchase1;
purchase1 = new Purchase();

After you’ve created the code in Listing 17-2, the word Purchase stands for a brand-new type — a reference type. Java has eight built-in primitive types and has as many reference types as people can define during your lifetime. In Listing 17-2, I define the Purchase reference type, and you can define reference types, too.

Table 17-2 has a brief comparison of primitive types and reference types.

TABLE 17-2 Java Types

Primitive Type

Reference Type

How it’s created

Built into the language

Defined as a Java class

How many are there

Eight

Indefinitely many

Sample variable declaration

int count;

Purchase aPurchase;

Sample assignment

count = 0;

aPurchase =

new Purchase();

Assigning a value to one of its parts

(Not applicable)

aPurchase.unitPrice =

20.00;

Another Way to Think about Classes

When you start learning object-oriented programming, you may think that this class idea is a big hoax. Some geeks in Silicon Valley had nothing better to do, so they went to a bar and made up some confusing gibberish about classes. They don’t know what it means, but they have fun watching people struggle to understand it.

Well, that’s not what classes are all about. Classes are serious stuff. What’s more, classes are useful. Many reputable studies have shown that classes and object-oriented programming save time and money.

Even so, the notion of a class can be elusive. Even experienced programmers — the ones who are new to object-oriented programming — have trouble understanding how an object differs from a class.

Classes, objects, and tables

Because classes can be mysterious, I’ll expand your understanding with another analogy. Figure 17-7 has a table of three purchases. The table’s title consists of one word (the word Purchase), and the table has three column headings: the words unitPrice, quantity, and taxable. Well, the code in Listing 17-2 has the same stuff — Purchase, unitPrice, quantity, and taxable. So in Figure 17-7, think of the top part of the table (the title and column headings) as a class. Like the code in Listing 17-2, this top part of the table tells you what it means to be a Purchase. (It means having an unitPrice value, a quantity value, and a taxable value.)

image

FIGURE 17-7: A table of purchases.

A class is like the top part of a table. And what about an object? Well, an object is like a row of a table. For example, with the code in Listing 17-5, I create two objects (two instances of the Purchase class). The first object has unitPrice value 20.00, quantity value 3, and taxable value true. In the corresponding table, the first row has these three values — 20.00, 3, and true, as shown in Figure 17-8.

image

FIGURE 17-8: A purchase corresponds to a row of the table.

Some questions and answers

Here’s the world’s briefest object-oriented programming FAQ:

  • Can I have an object without having a class?

    No, you can’t. In Java, every object is an instance of a class.

  • Can I have a class without having an object?

    Yes, you can. In fact, almost every program in this book creates a class without an object. Take Listing 17-5, for example. The code in Listing 17-5 defines a class named ProcessPurchases. And nowhere in Listing 17-5 (or anywhere else) do I create an instance of the ProcessPurchases class. I have a class with no objects. That’s just fine. It’s business as usual.

  • After I’ve created a class and its instances, can I add more instances to the class?

    Yes, you can. In Listing 17-5, I create one instance and then another. In a for loop, I could create a dozen instances and I’d have a dozen rows in the table of Figure 17-8. With no objects, three objects, four objects, or more objects, I still have the same old Purchase class.

  • Can an object come from more than one class?

    Bite your tongue! Maybe other object-oriented languages allow this nasty class cross-breeding, but in Java, it’s strictly forbidden. That’s one thing that distinguishes Java from some of the languages that preceded it: Java is cleaner, more uniform, and easier to understand.

What’s Next?

Listing 17-5 contains some code that makes me nervous. In Listing 17-5, the statements that compute a purchase total appear once, and then appear a second time with only one tiny change:

double purchase1Total = purchase1.unitPrice * purchase1.quantity;
if (purchase1.taxable) {
purchase1Total *= 1.05;
}

double purchase2Total = purchase2.unitPrice * purchase2.quantity;
if (purchase2.taxable) {
purchase2Total *= 1.05;
}

To me, this repetition seems silly. Aren’t computers supposed to save us from mundane burdens such as repetitive typing? What if I type these statements correctly the first time, but make a mistake the second time? Maybe I’ll copy the bad version a third and fourth time and end up with code that’s all messed up!

Repetitive code is error-prone. It’s inconvenient and unnecessary. Instead of repeating code, you should be able to summarize your code and then refer to that summarized code repeatedly. With Java’s methods, you have precisely that capability. You’ve used other peoples’ methods in many examples throughout this book, and in Chapter 19, you create methods of your own.

tryitout This is your chance to write some very classy code.

WHAT’S YOUR BMI?

A person’s body mass index (BMI) is the person’s weight (in kilograms) divided by the square of the person’s height (in meters). For example, a 65 kg person who’s 1.65 meters tall has a BMI of 23.875.

  • Create a Person class. Each Person has a weight and a height. In other words, the Person class has two fields: a weight field (a double value) and a height field (another double value).
  • Create another class containing a main method. In the main method, create a Person object. Assign values to the Person object’s weight and height fields by reading input from the keyboard. Use the Person object’s weight and height fields to calculate the person’s BMI. Then output the person’s BMI.
  • Modify the main method that you wrote for the previous bullet so that it creates three Person objects and calculates each object’s BMI.

A BIT OF MACROECONOMICS

A country’s debt-to-GDP ratio is the amount of the government’s debt divided by the country’s gross domestic product (GDP). For example, a country with 14.3 trillion dollars of debt and 18.5 trillion dollars GDP has a debt-to-GDP ratio of approximately 77 percent. A low debt-to-GDP ratio means that a country can pay off its debts without having to incur even more debt.

Try writing the following code:

  • Create a Country class. Each Country has a debt and a gdp. In other words, the Country class has two fields: a debt field (a double value) and a gdp field (another double value).
  • Create another class containing a main method. In the main method, create a Country object. Assign values to the Country object’s debt and gdp fields by reading input from the keyboard.

    Also in the main method, ask the user for an acceptable debt-to-GDP ratio. If your Country object’s debt-to-GDP ratio is lower than the acceptable value, output the words That’s acceptable. Otherwise, output That’s not acceptable.

  • Modify the main method that you wrote for the previous bullet so that it creates three Country objects and displays That’s acceptable or That’s not acceptable for each object.

NOTHING IN PARTICULAR

This program isn’t about a Purchase class, a Person class, a Country class, or about a class with any obvious real-world relevance:

  • Create a Thing class. The Thing class has two fields: a value1 field (an int value) and a value2 field (another int value).
  • Create another class containing a main method. In the main method, create a Thing object. Assign values to the Thing object’s value1 and value2 fields by reading input from the keyboard. Use the Thing object’s value1 and value2 fields to display a sentence about the object. A typical sentence might be

    This thing has values 42 and 91.

  • Modify the main method that you wrote for the previous bullet so that it creates three Thing objects and displays a sentence about each of them.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.104.124