|
 |
 |
[an error occurred while processing this directive]
In this How-To, you will create an application that uses inheritance. You will be using the Vehicle class from the previous How-To as a base class. You will create a new class that derives basic functionality from Vehicle.
Steps
- 1. Create a new subdirectory named CAR, change to that subdirectory, and start your source code editor.
- 2. Copy the files named VEHICLE.H and VEHICLE.CPP from the VEHICLE subdirectory (used in the last How-To). The file VEHICLE.H follows:
// vehicle.h - this file contains a class
// declaration for the vehicle type.
class Vehicle
{
public:
enum Switch { SWITCH_ON, SWITCH_OFF } ;
Vehicle( ) ;
~Vehicle( ) ;
bool powerSwitch( Switch onOrOff ) ;
unsigned int accelerate( unsigned int amount ) ;
unsigned int decelerate( unsigned int amount ) ;
bool isMoving( void ) const ;
unsigned int getSpeed( void ) const ;
unsigned int setSpeed( unsigned int speedIn ) ;
protected:
bool moving ;
private:
unsigned int speed ;
} ;
Please note that if your compiler does not support the bool data type, you can add the following line of code at the top of this header file:
enum bool { false = 0, true } ;
- 3. Create a new file called CAR.H and type the following class declaration:
// car.h - this file contains a class declaration
// for the Car type, derived from Vehicle
#include vehicle.h
class Car : public Vehicle
{
public:
enum { MAX_SPEED = 80 } ;
Car( ) ;
~Car( ) ;
unsigned int setSpeed( unsigned int speedIn ) ;
void steer( int degrees ) ;
void headLights( Switch onOrOff ) ;
private:
int degrees ;
Switch drivingLights ;
} ;
- 4. Create a file named CAR.CPP and type the following code:
// car.cpp implementation file
// for a Car; derived from Vehicle
#include car.h
Car::Car( ) : Vehicle(),
degrees( 0 ), drivingLights( SWITCH_OFF )
{
}
Car::~Car( )
{
degrees = 0 ;
drivingLights = SWITCH_OFF ;
}
unsigned int Car::setSpeed( unsigned int speedIn )
{
if( speedIn > MAX_SPEED )
speedIn = MAX_SPEED ;
Vehicle::setSpeed( speedIn ) ;
moving = true ;
return( Vehicle::getSpeed() ) ;
}
void Car::steer( int degrees )
{
if( moving )
{
if( degrees == 0 )
this->degrees = 0 ;
else
this->degrees += degrees ;
}
}
void Car::headLights( Switch onOrOff )
{
drivingLights = onOrOff ;
}
- 5. Save CAR.CPP and create a file named MAIN.CPP. This file should contain the following:
#include <iostream>
using namespace std ;
#include car.h
int main( )
{
Car *sporty = new Car() ;
Car *luxury = new Car() ;
sporty->setSpeed( 120 ) ;
luxury->setSpeed( 35 ) ;
luxury->steer( 20 ) ; // turn to right
luxury->headLights( Vehicle::SWITCH_ON ) ;
luxury->accelerate( 15 ) ;
cout << sportys speed : << sporty->getSpeed() << endl ;
cout << pLuxurys speed: << luxury->getSpeed() << endl ;
if( sporty->isMoving( ) )
cout << sporty is moving << endl ;
else
cout << sporty isnt moving << endl ;
delete luxury ;
delete sporty ;
return 0 ;
}
- 6. Save MAIN.CPP and return to the command line. Next, compile and link MAIN.CPP, VEHICLE.CPP, and CAR.CPP as shown in the following:
gcc -c main.cpp vehicle.cpp car.cpp
If your compiler complains about the statement
#include <iostream>
comment out (or remove) the using directive following it and change the #include line to
#include <iostream.h>
- 7. Run the program; the output should be as follows:
sportys speed : 80
pLuxurys speed: 50
sporty is moving
If you are using the DJGPP compiler, you might have to rename the executable from A.OUT to MAIN.EXE to execute the program.
How It Works
Lets start by examining the file CAR.H. In this file, you find the declaration of the user-defined type Car. After the #include directive, you come to the declaration for Car, as shown following:
class Car : public Vehicle
The keyword class introduces a user-defined type, followed by the name. Next is the colon operator, followed by the public keyword and a class name. The colon operator introduces one or more base classes from which this class derives. The derived class is Car and the base class is Vehicle. This is known as an is-a relationship; in other words, Car is-a Vehicle. This is the same as any other inheritance relationship you find in the world around you. A dog is-a mammal. A house is-a building, and so on. So, Car inherits from Vehicle.
Next you find the public access specifier, followed by a class scope constant named MAX_SPEED. Then come the constructor, destructor, and three member functions.
The first member function, setSpeed, is also found in the base class Vehicle. The member function setSpeed is overridden in Car because the signatures in Vehicle and Car match exactly. In other words, the function in Car is redefined because Car specializes the functionality.
The next function declaration
void steer( int degrees ) ;
is a new member function introduced for Car. Obviously, you have to steer a Car, so this member function provides that functionality. You are probably asking, All vehicles must be steerable, so why not provide that function in Vehicle? Think about a train. The engineer does not actually steer the train because the act of steering a train is controlled by the train tracks. When deciding on your abstractions, you have to think about minimal functionality in the base class. This style of thinking will remove any restrictions that might be passed on to derived classes. For example, if you had declared the function steer in the base class, and decided to create a derived train class, you would end up with an invalid interface. A client developer will take a look at the available interface and wonder what the steer function will provide for a train.
|