Chapter 3

Object-Oriented Programming

Starting from this lesson you’ll be studying various elements of the Java language with brief descriptions to get you started programming in the shortest possible time. But you are certainly encouraged to refer to the extensive Java documentation that’s available online at http://java.sun.com/javase/6/docs/.

Classes and Objects

Java is an object-oriented language, which means that it has constructs to represent objects from the real world. Each Java program has at least one class that knows how to do certain things or how to represent some type of object. For example, the simplest class, HelloWorld, knows how to greet the world.

Classes in Java may have methods (aka functions) and fields (aka attributes or properties).

Let’s create and discuss a class named Car. This class will have methods, describing what this type of vehicle can do, such as start the engine, shut it down, accelerate, brake, lock the doors, and so on.

This class will also have some fields: body color, number of doors, sticker price, and so on.

download.eps

Listing 3-1: Class Car

class Car{
    String color;
    int numberOfDoors;
 
    void startEngine {
       // Some code goes here
    }
    void stopEngine {
         int tempCounter=0;  
      // Some code goes here
    }
}

Lines that start with double slashes are comments, which will be explained later in this lesson.

Car represents common features for many different cars: All cars have such properties as color and number of doors, and all of them perform similar actions. You can be more specific and create another Java class called Car. It’s still a car, but with some properties specific to the model James Bond. You can say that the class JamesBondCar is a subclass of Car, or, using Java syntax, JamesBondCar extends Car.

download.eps

Listing 3-2: Class JamesBondCar

class JamesBondCar extends Car{
    int currentSubmergeDepth;
    boolean isGunOnBoard=true;
    final String MANUFACTURER; 
 
    void submerge {
        currentSubmergeDepth = 50;
       // Some code goes here
    }
    void surface {
      // Some code goes here
    }
}

But even after defining all the properties and methods for the class JamesBondCar you can’t drive it, even on the computer screen. A Java class is like a blueprint in construction or engineering, and until you build real objects based on this blueprint you can’t use them.

Creating objects, aka instances, based on classes is the equivalent of building real cars based on blueprints. To create an instance of a class means to create the object in the computer’s memory based on the class definition.

To instantiate a class (to put one more car on the road), you’ll declare a variable of this class’s type, and use the new operator for each new instance of the car:

JamesBondCar car1 = new JamesBondCar();
JamesBondCar car2 = new JamesBondCar();

Now the variables car1 and car2 can be used to refer to the first and second instance of the JamesBondCar respectively. To be precise, declaring the variables pointing at the instances is needed if you are planning to refer to these instances in the program. The statement new JamesBondCar() creates the instance, too. You can create many cars based on the same specification. Even though they all represent the same class, they may have different values in their properties — some of them are red, some of them have two doors while others have four, etc.

Variables, Constants, and Data Types

Some values representing an object can change over time (variables) and some remain the same (constants). This section will shed more light on the use of both types.

Declaring Variables

Java is a statically typed language: The program variables must be declared (named and typed) first, and then you can assign them values either at the time of declaration or later on in one of the class methods. For example, the variable isGunOnBoard has been initialized during its declaration in Listing 3-2, and currentSubmergeDepth got its value in the method submerge().

The class Car from Listing 3-1 defines a variable color of type String, which is used to represent text values.

Constants

To store values that never change, you need to declare a constant — just add the keyword final to the declaration line, as in Listing 3-2:

final String MANUFACTURER; 

Java developers usually render the names of constants in upper case. The value of a constant can be assigned only once, and since you are creating an instance of a specific car, its manufacturer is known and can’t change during the life span of this object:

 MANUFACTURER = "J.B. Limited"; 

Even though you don’t have to initialize final variables during their declaration, it is a good practice to follow. The preceding example should be written as

final String MANUFACTURER="J.B. Limited"; 

Primitive Data Types

There are eight primitive data types in Java: Four are for integer values, two are for values with a decimal point, one is for storing single characters, and one is for Boolean data that allows only either true or false as a value. Following are some examples of variable declarations and initializations:

int chairs = 12;
char grade = 'A';                            
boolean cancelJob = false;         
double nationalIncome = 23863494965745.78; 
float hourlyRate = 12.50f;   // add an f at the end of        
                             //float literals
long totalCars  = 4637283648392l;  // add an l at the end             
                                   // of long literals

The following table summarizes some characteristics of the Java data types.

tab0301

Have you noticed that the char data type uses two bytes of memory to store the data? This allows you to store character sets that have a lot more symbols than traditional alphabets because a single byte can only represent 256 characters, while two bytes can represent 65,536 characters.

Following are some examples of variable declarations and initializations:

int chairs = 12;                            
boolean cancelJob = false;         
double nationalIncome = 23863494965745.78; 
float hourlyRate = 12.50f; 
long totalCars  = 4637283648392L;                              

The last two literals in the preceding list end with the letters f and L to indicate that you want to store these data as float and long data types correspondingly. But most likely, the double datatype should fit all your needs in non-integer calculations.

Variable Scope

If you declare a variable inside any method, the variable has a local scope (for example, adjustedTax in Listing 3-5 is local). This means that it’s only visible for the code within this method (calcTax). When the method completes its execution, all local variables are automatically removed from memory by Java’s garbage collector. Actually the scope is tighter than that. It’s accessible within the method only after the variables are declared, and only within the block in which it is declared. For instance, a variable declared inside a for loop will not be excessive outside the for loop even inside the same method.

If a variable has to be accessible from more than one class method, declare it on a class level. Listing 3-5 shows the class Tax, where grossIncome, dependents, and state are class or member variables. These variables are “alive” while the Tax object exists in memory. They can be shared and reused by all methods within the class and they can even be visible from external classes.

note.ai

If a variable is declared with a static qualifier (see Lesson 4), it’s shared by all instances of the class.

Wrappers, Autoboxing, and Unboxing

All primitive data types have corresponding wrapper classes that contain useful methods dealing with respective data types. The wrapper classes serve two purposes:

1. They contain a number of useful functions for manipulation with their primitive counterparts. For example, the class Integer offers such useful methods as conversion of a String into an int, or turning an int into a float, and more. The Integer class also allows you to set the minimum and maximum values for the number in question.

2. Some Java collections can’t store primitives (such as ArrayList) and so primitives have to be wrapped into objects. For example,

ArrayList myLotteryNumbers = new ArrayList();
myLotteryNumbers.add(new Integer(6)); 
myLotteryNumbers.add(new Integer(15));

You don’t need to explicitly create a new instance for every primitive as in the preceding code snippet. You can simply write myLotteryNumbers.add(6); and the primitive value 6 will automatically be wrapped into an instance of the Integer class. This feature is called autoboxing.

On the same note, the next line is also valid:

int luckyNumber= myLotteryNumber.get(23);

Even though get(23) will return the value of the 24th element (the numbering in Java collections starts with zero) as an Integer object, that object will automatically be converted into a primitive. This is called unboxing.

Program Comments

While writing code in Java, you should add comments, the text that explains what the program does. Programs are being read a lot more often than they are being written. At some point, other software developers will read and try to understand your code. Be nice and make their job easier. A typical software developer doesn’t like writing comments (regardless of what programming language he or she uses).

I can suggest to you a simple technique: Write comments first and only then the code. By the time your program is written it’s already commented. You can write comments pretty much everywhere — before or inside the class, or inside the methods.

In Java you can use three types of comments:

  • Block comments that contain more than one line of text located between the symbols /* and */. For example:
               /* This method will calculate the cost of shipping, handling,  
                    and all applicable taxes
               */
    

The compiler ignores the text in comments and you can write whatever you want.

  • If you want to write a short comment that fits on a single line, just start this line with two forward slashes (//). For example:
    // This method will calculate the cost of shipping
    
  • Some comments start with /** and end with */. These are used by a special utility, javadoc, that can automatically extract the text from these comments and create program documentation. To get a feeling for what javadoc can generate, look at the documented API for Java itself http://java.sun.com/javase/6/docs/api/overview-summary.html.

If you’d like to learn how to use the javadoc utility, refer to its program documentation at http://java.sun.com/javase/6/docs/technotes/guides/javadoc/index.html.

First Useful Program

It’s time to write a program that does something more useful than print “Hello World.” This program will emulate the calculation of state tax. The goal is to show you how Java classes communicate, how methods are called, and how variables can be used.

First you need to decide what Java class(es) you need to write for the task at hand. Then think about the properties (class variables) and methods (functions) these classes should have.

Declaring a Tax Class with Properties

Since you are planning to calculate tax, it doesn’t take a rocket scientist to figure out that you need to define a class called Tax. Start with the class name and curly braces — this is the simplest class you can create:

class Tax{
}

What data does this class need to perform tax calculations? You’ll definitely need to know the gross income of a person for the tax year. This is a good candidate for a property of this class. Properties in Java are represented by variables. Pick one of the numeric data types. Gross income is not always an integer number, so let’s use the double data type, as it’s a number with a decimal point. You could use float instead, but you expect to process some very large incomes:

 class Tax{   
       double grossIncome;
 }

You also need to know what state the person lives in — taxation rules vary by state. These are some of the abbreviations for the states in the USA: NY, NJ, CT. Use the data type String for storing text data:

class Tax{   
       double grossIncome;
       String state;
 }

Add one more property for dependents of the taxable person. Integer will work just fine here — a person can’t have two and a half dependents:

class Tax{   
       double grossIncome;
       String state;
       int  dependents;
 }

Adding a Method to the Tax Class

Variables store data, and methods perform actions. It’s time for actions. The first method, calcTax(), will calculate the state tax based on the values of gross income, number of dependents, and state:

download.eps

Listing 3-3: Class Tax

class Tax{   
          double grossIncome;
          String state;
          int dependents;
      
          public double calcTax() {
           
             return 234.55;  
          }
}

The calcTax() method signature tells the following:

  • Any external class can access this method (public).
  • This method will return a value of type double.
  • The name of the method is calcTax.

The empty parentheses after the method name mean that it does not have any arguments or, in other words, it does not need any values from outside Tax to perform calculations. As a matter of fact, this version of calcTax() doesn’t use any data for calculation — it just returns a hard-coded tax value of $234.55.

How do you decide if a method should return a value? If your method performs some calculations and has to give a value back to a calling program, it has to return a value. If a method directly modifies the class variables or simply outputs data somewhere (monitor, disk, server) it may not need to return any values. You still need to declare a “no return” in a method signature by using a special keyword, void:

public void PrintAnnualTaxReturn() {
  
    //Code goes here
} 

With the Java return statement a method can return data contained in a variable to a calling program, for example:

return calculatedTax; 

Keep in mind that if you declare a return type in the method signature but forget to include the return statement in the body of the method, the Java compiler will give you an error.

Declaring Another Class: TestTax

Tax will know how to calculate tax, but in a real-world application you’ll have many classes that represent the various workflows of this process. For example, you may need to create a class called Customer. Depending on the type of employment or income, accountants use many different forms to file taxes, and each form can be represented by a separate class: Form1040, Form1099, and so on.

Each of these classes represents some entity, but none of them is an executable program — none of them will have the method main(). You need to create one more class to start the application and instantiate other classes as needed. I’ll call this class TestTax. The class TestTax should be able to perform the following actions:

  • Create an instance of the class Tax.
  • Assign customer’s data (gross income, state, dependents) to the class variables of the class Tax.
  • Call the method calcTax().
  • Print the result on the screen.

The class TestTax will be stored in a separate file named TestTax.java.

download.eps

Listing 3-4: Class TestTax

class TestTax{
     public static void main(String[] args){
            Tax   t = new Tax(); // creating an instance
            t.grossIncome= 50000;  // assigning the values
            t.dependents= 2;
            t.state= "NJ";
                             
            double yourTax = t.calcTax(); //calculating tax 
                            
           // Printing the result 
           System.out.println("Your tax is " + yourTax);
     } 
 }

In the preceding code we’ve declared a variable, t, of type Tax.

The method main() is an entry point to the tax-calculation program. This method creates an instance of the class Tax and the variable t points to a place in your computer’s memory where the Tax object was created. From now on, if you want to refer to this object use the variable t.

The following three lines assign values to the properties of the object Tax:

            t.grossIncome= 50000;  // assigning the values
            t.dependents= 2;
            t.state= "NJ";

After that you can calculate tax by calling the method calcTax(), and the result returned by this method will be assigned to the variable yourTax. The method calcTax() still returns the hard-coded value, but you’ll fix this in the “Try It” section of this lesson. The last line just displays the result on the system console.

At this point we already have two classes communicating with each other (TestTax and Tax).

Conditional Statement if

We make decisions all the time: “If she says this I’ll answer with that, otherwise I’ll do something else.” Java has an if statement that determines whether some condition is true or false. Based on the answer to this question the execution of your program will be routed.

If the condition expression returns true, the code between the first curly braces will be executed; otherwise the code after the else statement will take place. For example:

if (totalOrderPrice > 100){
         System.out.println("You'll get a 20% discount");
}
else{
         System.out.println("Order books for more than a" + 
                            " $100 to get a 20% discount");
}

Because this code sample has only one statement to execute in the if and else clauses, using curly braces is not a must, but they make the code more readable and prevent you from introducing hard-to-find bugs if, later on, you need to add more code in an if statement.

switch Statement

The switch statement is an alternative to if. The case label in the switch condition (taxCode) is evaluated and the program goes to one of the following case clauses:

int taxCode=someObject.getTaxCode(grossIncome);
switch (taxCode){
   case 0:
     System.out.println("Tax Exempt");
     break;
   case 1:
     System.out.println("Low Tax Bracket");
     break;
   case 2:
     System.out.println("High Tax Bracket");
     break;
   default:
     System.out.println("Wrong Tax Bracket");
 
}

The preceding code will call only one println() method. Do not forget to put the break at the end of each case statement so the program will jump out of the switch statement after processing a case; otherwise the code will “fall-through” and print more than one line even though a taxCode can have only one value.

Inheritance

In object-oriented languages the term inheritance means an ability to define a new class based on an existing one (not from scratch).

Imagine that the class Tax calculates tax properly in all states except New Jersey, which has introduced new educational tax deductions. If you have a kid in college, this makes you eligible for an additional $500 deduction from your taxes. In this case you have to either change the method calcTax()in the class Tax to introduce a special case for New Jersey, or create another class based on Tax and add this new functionality there.

Every person inherits some features from his or her parents. A similar mechanism exists in Java. The special keyword extends is used to indicate that one class has been inherited from another:

class NJTax extends Tax{
}

The class NJTax will have all the features the class Tax has, plus you can add new properties and methods to it. In such a setup, the class Tax is called a superclass, and NJTax is called a subclass. You can also use the terms ancestor and descendent, respectively. This new class will have access to all variables and methods of its superclass, unless those have a private or package access level, which will be discussed in Lesson 5.

Let’s extend the behavior of the class Tax in NJTax. The latter will have a method called adjustForStudents():

download.eps

Listing 3-5: Class NJTax

class NJTax extends Tax{
 
    double adjustForStudents (double stateTax){
       double adjustedTax = stateTax – 500;
       return adjustedTax;
    }
}

To use this new method, the TestTax class should instantiate NJTax rather than Tax as it did in Listing 3-4:

NJTax  t= new NJTax();

Now you can call methods defined in the class Tax as well as those from NJTax using the reference variable t, for example:

NJTax  t= new NJTax();
double yourTax = t.calcTax();  
double totalTax = t. adjustForStudents (yourTax);

I’ve added a new functionality to the tax-calculation program without changing the code of the class Tax. The preceding code fragment also shows how you can pass a result of processing from one method to another. The value of the variable yourTax was calculated by calcTax() and is passed to the method adjustForStudents() as an argument.

Method Overriding

Yet another important term in object-oriented programming is method overriding. Imagine Tax with 20 methods. Most of them work fine for all states, but there is one method that is not valid for New Jersey. Instead of modifying this method in the superclass, you could create another method in the subclass with the same name and argument list. If a subclass has that method with the same name and argument list, it will override (suppress) the corresponding method of its ancestor.

Method overriding comes in handy in the following situations:

  • The source code of the superclass is not available, but you still need to change its functionality.
  • The original version of the method is still valid in some cases and you want to keep it intact.
  • You use method overriding to enable polymorphism, which will be explained in Lesson 7.

You’ll have a chance to try method overriding in the “Try It” section. In Lesson 4 you learn about method overloading, which is a completely different animal.

Try It

In this section you create in Eclipse the tax-calculation application described in this lesson, and then modify it to replace the hard-coded value returned by the method calcTax() with some calculations. After this is done, you’ll subclass the class Tax and override calcTax().

Lesson Requirements

For this lesson you must have Eclipse IDE installed.

note.ai

You can download the code and resources for this Try It from the book’s web page at www.wrox.com. You can find them in the Lesson3 folder in the download.

Hints

This lesson has only brief introductions to basic Java language constructs. The online Java tutorial may be handy while completing this and future assignments. It’s available at http://download.oracle.com/javase/tutorial/java/index.html.

Step-by-Step

1. In Eclipse, create a new project named Lesson 3.

2. Create a new Tax class (File New Class). Enter the code shown in Listing 3-3.

3. Create another class, TestCalc, and input the code from Listing 3-4.

4. Save both classes and run TestCalc (right-click and select Run As Java Application). The console view should display “Your tax is 234.55,” as shown in Figure 3-1.

5. Replace the return of a hard-coded value with some tax calculations. Let’s say that if the gross income was less than $30,000 you will deduct 5 percent for state tax. If it’s greater than $30,000 you will deduct 6 percent. Modify the code of calcTax as follows. Run the program several times, modifying the values of the class variables of the class Tax. Make sure that the tax value on the console is properly calculated.

public double calcTax() {         
      double  stateTax=0;
      if (grossIncome < 30000) {
        stateTax=grossIncome*0.05;
      }
      else{
        stateTax= grossIncome*0.06;
      } 
        return stateTax;
}

6. Create the NJTax class shown in Listing 3-5.

7. Change the functionality of calcTax()by overriding it in NJTax. The new version of calcTax()should lower the tax by $500 before returning the value.

8. Modify the code of the TestTax class to instantiate NJTax instead of Tax. Observe that the $500 deduction is properly calculated.

To get the sample database files you can download Lesson 3 from the book’s website at www.wrox.com.

cd.ai

Please select Lesson 3 on the DVD with the print book, or watch online at www.wrox.com/go/fainjava to view the video that accompanies this lesson.

..................Content has been hidden....................

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