Chapter 6. Classes

   

Java™ 2 Primer Plus
By Steven Haines, Steve Potts

Table of Contents
Part II:  Object-Oriented Programming


You will learn about the following in this chapter:

  • Basics of object-oriented programming, including encapsulation and information hiding

  • Java classes and how to use them

  • Constructors

  • Scoping rules

  • Access modifiers

  • The this variable

  • Garbage collection

  • Inner classes

  • Object references

At this point in the book you have learned all the basic tools required to build computer programs: data types, variables, operators, conditional statements, iterative statements, and methods. You learned how a large problem can be broken down into smaller sub-problems that are easier to solve through a technique called divide and conquer. Divide and conquer was successful in solving a specific set of problems, but now I want to turn your attention toward solving a generic set of problems.

With the techniques discussed thus far, how could you represent a car in Java? What are the attributes of a car? What are the types of actions you can perform on or with a car?

The attributes of a car can represent both physical properties as well as the state of the car (see Tables 6.1 and 6.2).

Table 6.1. Physical Attributes of a Car

Attribute

Description

Engine

The type of engine

Wheels

Four wheels these could have attributes of their own: remaining tread, temperature, amount of air

BodyType

The type of the body: coupe, convertible, targa top

Windshield

The type and style of windshield

Doors

Four doors

Radiator

The car's radiator

TopSpeed

How fast can the car go?

Gas cap

You get the point…

Table 6.2. State Attributes of a Car

Attribute

Description

Running

Is the car running?

CurrentSpeed

What is the current speed of the car?

CurrentOil

How much oil does the car have?

CurrentFuel

How much gas does the car have?

Direction

What direction is the car facing?

GlobalLocation

The location of the car (using a GPS system)

Tables 6.1 and 6.2 show a small subset of all the attributes that could describe a car or its state.

Now consider the actions that a car can perform or that you can perform with a car (see Table 6.3).

Table 6.3. Car Actions

Action

Description

TurnOn

Start the car

TurnOff

Turn off the car

Accelerate

Accelerate the car

Decelerate

Decelerate the car

Turn

Change the car's direction (right or left)

AddGas

Increase the car's fuel

AddOil

Add oil to the car

With all these attributes and actions defined for a car, how might a car be represented in a Java program? The physical and state attributes could be represented by variables, and the actions could be represented by methods (see Listing 6.1).

Listing 6.1 CarTest.java
 public class CarTest {    static final int COUPE = 1;    static final int CONVERTIBLE = 2;    static final int T_TOP = 3;    static final int V4 = 1;    static final int V6 = 2;    static final int V8 = 3;    static final int V10 = 4;    static int engineType;    static int bodyType;    static int topSpeed;    static int gas;    static int oil;    static boolean isRunning;    static int currentSpeed;    public static void turnOn() {      isRunning = true;    }    public static void turnOff() {      isRunning = false;    }    public static void accelerate() {      switch( engineType ) {      case V4:        speedUp( 2 );        break;      case V6:         speedUp( 3 );        break;      case V8:        speedUp( 4 );        break;      case V10:        speedUp( 5 );        break;      }    }    public static void speedUp( int amount ) {      if( isRunning == false ) {        // Do nothing   car is not running!        return;      }      if( ( currentSpeed + amount ) >= topSpeed ) {        currentSpeed = topSpeed;      }      else {        currentSpeed += amount;      }    }    public static void decelerate() {      if( isRunning == false ) {        // Do nothing   car is not running!        return;       }      if( ( currentSpeed   5 ) <= 0 ) {        currentSpeed = 0;      }      else {        currentSpeed -= 5;      }    }    public static void main( String[] args ) {      // Define the attributes of the car      engineType = V10;      bodyType = CONVERTIBLE;      topSpeed = 185;      isRunning = false;      currentSpeed = 0;      // Do some things with the car      turnOn();      for( int i=0; i<10; i++ ) {         accelerate();        System.out.println( "Current Speed: " + currentSpeed );       }      for( int i=0; i<5; i++ ) {        decelerate();        System.out.println( "Current Speed: " + currentSpeed );      }      turnOff();    }  } 

The CarTest class defines several class variables and static methods that manipulate those variables; this effectively represents a car. Now what would happen if you want to represent two cars?

Using the techniques presented thus far you are forced to define a new set of variables and methods for the second car; for example, accelerate2(), speedUp2(), and so on. This creates considerably more work, but most of it revolves around copying the methods and renaming them it is not desirable but feasible.

Finally, what happens when you want to represent an arbitrary number of cars? These techniques cannot solve this problem!

The next evolutionary step in software development history was to group attributes into what are referred to as data structures. Data structures can contain multiple attributes, used to represent real-world objects such as a car. In Java a data structure is referred to as a class. Thus, you can define a Car class that contains all the attributes of a car, and then create methods that operate on a generic car. Listing 6.2 displays the code that represents a Car, and Listing 6.3 defines a new class CarTest2 that uses the Car class.

Listing 6.2 Car.java
 public class Car {    public static final int COUPE = 1;    public static final int CONVERTIBLE = 2;    public static final int T_TOP = 3;    public static final int V4 = 1;    public static final int V6 = 2;    public static final int V8 = 3;    public static final int V10 = 4;    public int engineType;    public int bodyType;    public int topSpeed;    public int gas;    public int oil;    public boolean isRunning;    public int currentSpeed;  } 
Listing 6.3 CarTest2.java
 public class CarTest2 {      public static void turnOn( Car c ) {        c.isRunning = true;      }      public static void turnOff( Car c ) {        c.isRunning = false;       }      public static void accelerate( Car c ) {        switch( c.engineType ) {        case Car.V4:          speedUp( c, 2 );          break;        case Car.V6:          speedUp( c, 3 );          break;        case Car.V8:          speedUp( c, 4 );          break;        case Car.V10:          speedUp( c, 5 );          break;        }      }      public static void speedUp( Car c, int amount ) {        if( c.isRunning == false ) {          // Do nothing - car is not running!          return;        }        if( ( c.currentSpeed + amount ) >= c.topSpeed ) {          c.currentSpeed = c.topSpeed;        }        else {          c.currentSpeed += amount; }      }      public static void decelerate( Car c ) {        if( c.isRunning == false ) {          // Do nothing - car is not running!          return;        }        if( ( c.currentSpeed - 5 ) <= 0 ) {          c.currentSpeed = 0;        }        else {          c.currentSpeed -= 5;        }         }      public static void main( String[] args ) {        // Define the attributes of the car        Car c1 = new Car();        c1.engineType = Car.V10;        c1.bodyType = Car.CONVERTIBLE;        c1.topSpeed = 185;        c1.isRunning = false;        c1.currentSpeed = 0;        // Do some things with the car        turnOn( c1 );        for( int i=0; i<10; i++ ) {          accelerate( c1 );          System.out.println( "Current Speed: " + c1.currentSpeed );        }        for( int i=0; i<5; i++ ) {          decelerate( c1 );          System.out.println( "Current Speed: " + c1.currentSpeed );        }        turnOff( c1 );      }  } 

Listing 6.2 defines a new class named Car, which contains all the attributes that were defined as class variables in the CarTest example. Listing 6.3 defines a new class named CarTest2, which defines a main method that creates a new instance of the Car class and sends that Car instance to its set of methods.

To compile these two classes, put the contents of the Car class into a file named Car.java, and the contents of the CarTest2 class into a file named CarTest2.java and place both files in the same directory. You can then compile the classes individually:

 javac Car.java  javac CarTest2.java 

Or, you can compile the CarTest2 class and it will find the Car class for you. Remember that you can only launch classes that have a main method in them, so you cannot launch the Car class directly; you can however launch the CarTest2 class and it will reference the Car class for you:

 java CarTest2 

Looking at the code for the CarTest2 class, class instances are created using the Java keyword new. The general form of the new keyword is

 ClassName var = new ClassName(); 

Thus, the data type of var is ClassName and it is assigned the value of a new instance of ClassName. This is accomplished in CarTest2 as follows:

 Car c1 = new Car(); 

So, c1 is a Car and is assigned the value of a new instance of a Car. Just like you can use a variable that is an int or a char, you can use a Car variable. Classes are a little different from primitive data types such as ints and chars in that they have attributes that can be accessed using the dot (.) operator. To access the car's engineType attribute, you reference the Car instance variable, append a dot to it, and then reference the attribute by name:

 c1.engineType = Car.V10; 

This statement accesses c1's engineType attribute and assigns it the value Car.V10. The Car class defines a set of constants that represent engine type values that are static. Remember that there is only one instance of all static variables and methods for all instances of a class. Therefore, the V10 attribute can be accessed by specifying the class name Car and the attribute V10 without using the Car instance c1. The attributes however, are not static and are thus associated with a specific instance of the Car class. If you define two Car instances, they will share the same static constant values, but they will have their own engine type, body type, and top speed.

All the methods in the CarTest2 class are defined to accept an instance of the Car class as the first parameter these methods manipulate the attributes of a Car instance. You can therefore create one hundred different instances of the Car class and pass each one to any of these methods, and they would know how to manipulate the car.

Classes used as data structures solve a vast array of problems. They are an abstraction of disparate data types combined to represent a real-world object. Until the early '90s this is how almost all programming problems were solved, but there is still one set of problems. The accelerate method works great for a Car, but what about accelerating a Truck or a Motorcycle? What does a Truck's attribute care about a method that can manipulate a Car? If a Car's accelerate method is going to exclusively operate on a Car, why is it in a global area that everyone can see and not directly associated with a Car?

The answer lies in a development paradigm that appeared in the mainstream in the early '90s called object-oriented programming.


       
    Top
     



    Java 2 Primer Plus
    Java 2 Primer Plus
    ISBN: 0672324156
    EAN: 2147483647
    Year: 2001
    Pages: 332

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net