We now modify our implementation to incorporate inheritance, using class Withdrawal
as an example.
1. If a class A
is a generalization of class B
, then class B
is derived from (and is a specialization of) class A
. For example, abstract base class Transaction
is a generalization of class Withdrawal
. Thus, class Withdrawal
is derived from (and is a specialization of) class Transaction
. Figure 23.12 contains a portion of class Withdrawal
’s header file, in which the class definition indicates the inheritance relationship between Withdrawal
and Transaction
(line 9).
1 // Fig. 23.12: Withdrawal.h
2 // Definition of class Withdrawal that represents a withdrawal transaction
3 #ifndef WITHDRAWAL_H
4 #define WITHDRAWAL_H
5
6 #include "Transaction.h" // Transaction class definition
7
8 // class Withdrawal derives from base class Transaction
9 class Withdrawal : public Transaction
10 {
11 }; // end class Withdrawal
12
13 #endif // WITHDRAWAL_H
2. If class A
is an abstract class and class B
is derived from class A
, then class B
must implement the pure virtual
functions of class A
if class B
is to be a concrete class. For example, class Transaction
contains pure virtual
function execute
, so class Withdrawal
must implement this member function if we want to instantiate a Withdrawal
object. Figure 23.13 contains the C++ header file for class Withdrawal
from Fig. 23.10 and Fig. 23.11. Class Withdrawal
inherits data member accountNumber
from base class Transaction
, so Withdrawal
does not declare this data member. Class Withdrawal
also inherits references to the Screen
and the BankDatabase
from its base class Transaction
, so we do not include these references in our code. Figure 23.11 specifies attribute amount
and operation execute
for class Withdrawal
. Line 19 of Fig. 23.13 declares a data member for attribute amount
. Line 16 contains the function prototype for operation execute
. Recall that, to be a concrete class, derived class Withdrawal
must provide a concrete implementation of the pure virtual
function execute
in base class Transaction
. The prototype in line 16 signals your intent to override the base class pure virtual
function. You must provide this prototype if you’ll provide an implementation in the .cpp
file. We present this implementation in Section 23.4. The keypad
and cashDispenser
references (lines 20–21) are data members derived from Withdrawal
’s associations in Fig. 23.10. In the implementation of this class in Section 23.4, a constructor initializes these references to actual objects. Once again, to be able to compile the declarations of the references in lines 20–21, we include the forward declarations in lines 8–9.
1 // Fig. 23.13: Withdrawal.h
2 // Definition of class Withdrawal that represents a withdrawal transaction
3 #ifndef WITHDRAWAL_H
4 #define WITHDRAWAL_H
5
6 #include "Transaction.h" // Transaction class definition
7
8 class Keypad; // forward declaration of class Keypad
9 class CashDispenser; // forward declaration of class CashDispenser
10
11 // class Withdrawal derives from base class Transaction
12 class Withdrawal : public Transaction
13 {
14 public:
15 // member function overriding execute in base class Transaction
16 virtual void execute(); // perform the transaction
17 private:
18 // attributes
19 double amount; // amount to withdraw
20 Keypad &keypad; // reference to ATM's keypad
21 CashDispenser &cashDispenser; // reference to ATM's cash dispenser
22 }; // end class Withdrawal
23
24 #endif // WITHDRAWAL_H