In the previous chapter we created a CarObject class that represented a car, but now I want to create two specific types of cars: a Porsche and a Pinto. Before diving into the differences between these two types of cars, which my students have greatly enjoyed, I want to preface this discussion by telling you that when I was a child my grandparents replaced my mother's Chevy Super Sport with a Ford Pinto. All the presuppositions you might have about Pintos are quite true: max speeds reaching close to 60 mph on a downhill, and, yes, you do have to push the car up hills. So, before emailing me in opposition to the humorous comparison between a Porsche and a Pinto, rest assured that I am speaking from my own personal experience. Let's comprise a list of all the attributes we can think of specifically related to highly tuned Porsches. This list could include Horse power: about 450 Maximum speed: 220 mph Acceleration: 0 60 in 3.5 seconds Doors: 2 Paint: red or yellow, take your pick Turbos: 2 (twin turbo) Gas Oil Transmission: Tiptronic Nitrous Oxide System (NOS) The following could be methods that we could apply to the Porsche class: Start Stop Accelerate Decelerate Engage turbos Turn on NOS Turn off NOS Listing 7.1 shows a partial implementation of the code for the Porsche class. Listing 7.1 Porsche.java public class Porsche { public static final int TIPTRONIC = 1; // Attributes private int horsePower = 450; private int maximumSpeed = 220; private int numberOfDoors = 2; private String paint = "Yellow"; private int turbos = 2; private int gasCapacity = 15; private int oilCapacity = 5; private int transmission = TIPTRONIC; private boolean nos; // State attributes private boolean turbo1Engaged = false; private boolean turbo2Engaged = false; private boolean nosEnabled = false; private boolean running = false; private int currentSpeed; private int currentGas; private int currentOil; public Porsche() { } public void start() { running = true; } public void stop() { running = false; } public boolean isRunning() { return running; } public void accelerate() { // Check to see if we are running or not if( running == false ) { return; } // Create a variable representing how much we are going to // accelerate this second int increment = 15; // Check the turbos; they add 5mph per second acceleration if( turbo1Engaged ) { increment += 5; } if( turbo2Engaged ) { increment += 5; } // Check the NOS; it represents 15mph per second if( nos ) { increment += 15; } // Increment the current speed currentSpeed += increment; if( currentSpeed > maximumSpeed ) currentSpeed = maximumSpeed; } public void decelerate() { currentSpeed -= 20; if( currentSpeed < 0 ) currentSpeed = 0; } public void engageTurbos() { turbo1Engaged = true; turbo2Engaged = true; } public void disengageTurbos() { turbo1Engaged = false; turbo2Engaged = false; } public void engageNOS() { nos = true; maximumSpeed += 50; } public void disengageNOS() { nos = false; maximumSpeed -= 50; } public int getCurrentSpeed() { return currentSpeed; } public String toString() { return "A shiny new " + paint + " Porsche!"; } public static void main( String[] args ) { Porsche p = new Porsche(); System.out.println( "My new car: " + p ); p.start(); System.out.println( "Current speed: " + p.getCurrentSpeed() ); for( int i=0; i<20; i++ ) { if( i == 5 ) { p.engageTurbos(); } else if( i == 14 ) { p.engageNOS(); } p.accelerate(); System.out.println( "Current speed: " + p.getCurrentSpeed() ); } p.disengageNOS(); p.disengageTurbos(); while( p.getCurrentSpeed() > 0 ) { p.decelerate(); System.out.println( "Current speed: " + p.getCurrentSpeed() ); } p.stop(); } } The output of Listing 7.1 should be similar to the following: My new car: A shiny new Yellow Porsche! Current speed: 0 Current speed: 15 Current speed: 30 Current speed: 45 Current speed: 60 Current speed: 75 Current speed: 100 Current speed: 125 Current speed: 150 Current speed: 175 Current speed: 200 Current speed: 220 Current speed: 220 Current speed: 220 Current speed: 220 Current speed: 260 Current speed: 270 Current speed: 270 Current speed: 270 Current speed: 270 Current speed: 270 Current speed: 250 Current speed: 230 Current speed: 210 Current speed: 190 Current speed: 170 Current speed: 150 Current speed: 130 Current speed: 110 Current speed: 90 Current speed: 70 Current speed: 50 Current speed: 30 Current speed: 10 Current speed: 0 The main() method creates a new Porsche, starts it, accelerates it for five seconds, engages the turbos, accelerates for another nine seconds, and then kicks in the NOS. Finally, it turns off the turbos and the NOS and decelerates until the car stops. The code in the Porsche class is fairly self-explanatory, but there is one helpful method added called toString(). You might have noticed in the main() method that we printed the Porsche instance p: System.out.println( "My new car: " + p ); Whenever a class is used as a String, its toString() method is called, and the result of that method is added to the String. Thus, when we implement the toString method we can return a meaningful textual representation of our class; in this case: A shiny new Yellow Porsche! Now, on the other end of the spectrum we have the Pinto. The following could be attributes of the Pinto class: And the following could be methods of the Pinto class: Listing 7.2 shows a partial implementation of the code for the Pinto class. Listing 7.2 Pinto.java public class Pinto { public static final int MANUAL = 2; // Attributes private int horsePower = 50; private int maximumSpeed = 60; private int numberOfDoors = 5; private String paint = "Two-tone"; private int gasCapacity = 15; private int oilCapacity = 5; private int transmission = MANUAL; // State attributes private boolean running = false; private int currentSpeed; private int currentGas; private int currentOil; public boolean hatchBackDoorOpen = false; public Pinto() { } public void start() { // It isn't going to start ;) running = false; } public void stop() { running = false; } public boolean isRunning() { return running; } public void accelerate() { // Check to see if we are running or not if( running == false ) { return; } currentSpeed += 4; if( currentSpeed > maximumSpeed ) { currentSpeed = maximumSpeed; // The high speed knocked the door open! openHatchBack(); } } public void decelerate() { currentSpeed -= 5; if( currentSpeed < 0 ) currentSpeed = 0; } public int getCurrentSpeed() { return currentSpeed; } public void rollStart() { running = true; } public void pushUpHill() { System.out.println( "Ouch, this thing is heavy!" ); } public void openHatchBack() { hatchBackDoorOpen = true; } public void closeHatchBack() { hatchBackDoorOpen = false; } public boolean isHatchBackDoorOpen() { return hatchBackDoorOpen; } public String toString() { return "A rusty old " + paint + " Pinto"; } public static void main( String[] args ) { Pinto p = new Pinto(); System.out.println( "My car: " + p ); p.start(); if( p.isRunning() == false ) { System.out.println( "Starter failed, let's roll start it!" ); p.rollStart(); } System.out.println( "Current speed: " + p.getCurrentSpeed() + ", Hatchback open = " + p.isHatchBackDoorOpen() ); for( int i=0; i<20; i++ ) { p.accelerate(); System.out.println( "Current speed: " + p.getCurrentSpeed() + ", Hatchback open = " + p.isHatchBackDoorOpen() ); } while( p.getCurrentSpeed() > 0 ) { p.decelerate(); System.out.println( "Current speed: " + p.getCurrentSpeed() + ", Hatchback open = " + p.isHatchBackDoorOpen() ); } p.stop(); if( p.isHatchBackDoorOpen() ) { System.out.println( "Have to close the hatchback!" ); p.closeHatchBack(); } } } The output of Listing 7.1 should be similar to the following: My car: A rusty old Two-tone Pinto Starter failed, let's roll start it! Current speed: 0, Hatchback open = false Current speed: 4, Hatchback open = false Current speed: 8, Hatchback open = false Current speed: 12, Hatchback open = false Current speed: 16, Hatchback open = false Current speed: 20, Hatchback open = false Current speed: 24, Hatchback open = false Current speed: 28, Hatchback open = false Current speed: 32, Hatchback open = false Current speed: 36, Hatchback open = false Current speed: 40, Hatchback open = false Current speed: 44, Hatchback open = false Current speed: 48, Hatchback open = false Current speed: 52, Hatchback open = false Current speed: 56, Hatchback open = false Current speed: 60, Hatchback open = false Current speed: 60, Hatchback open = true Current speed: 60, Hatchback open = true Current speed: 60, Hatchback open = true Current speed: 60, Hatchback open = true Current speed: 60, Hatchback open = true Current speed: 55, Hatchback open = true Current speed: 50, Hatchback open = true Current speed: 45, Hatchback open = true Current speed: 40, Hatchback open = true Current speed: 35, Hatchback open = true Current speed: 30, Hatchback open = true Current speed: 25, Hatchback open = true Current speed: 20, Hatchback open = true Current speed: 15, Hatchback open = true Current speed: 10, Hatchback open = true Current speed: 5, Hatchback open = true Current speed: 0, Hatchback open = true Have to close the hatchback! The main() method creates a new Pinto instance, tries to start it, and when it fails, it roll starts the car. Then, it accelerates for 16 seconds to get to 60 miles per hour (I think I was quite generous) when the hatchback flies open. Finally, it decelerates to zero, and then closes the hatchback. |