Processing Transactions Polymorphically

A derived class can inherit interface and/or implementation from a base class. Compared to a hierarchy designed for implementation inheritance, one designed for interface inheritance tends to have its functionality lower in the hierarchy—a base class signifies one or more functions that should be defined by each class in the hierarchy, but the individual derived classes provide their own implementations of the function(s). The inheritance hierarchy designed for the ATM system takes advantage of this type of inheritance, which provides the ATM with an elegant way to execute all transactions “in the general.” Each class derived from Transaction inherits some implementation details (e.g., data member accountNumber), but the primary benefit of incorporating inheritance into our system is that the derived classes share a common interface (e.g., pure virtual member function execute). The ATM can aim a Transaction pointer at any transaction, and when the ATM invokes execute through this pointer, the version of execute appropriate to that transaction (i.e., the version implemented in that derived class’s .cpp file) runs automatically. For example, suppose a user chooses to perform a balance inquiry. The ATM aims a Transaction pointer at a new object of class BalanceInquiry; the compiler allows this because a BalanceInquiry is a Transaction. When the ATM uses this pointer to invoke execute, BalanceInquiry’s version of execute is called.

This polymorphic approach also makes the system easily extensible. Should we wish to create a new transaction type (e.g., funds transfer or bill payment), we would just create an additional Transaction derived class that overrides the execute member function with a version appropriate for the new transaction type. We would need to make only minimal changes to the system code to allow users to choose the new transaction type from the main menu and for the ATM to instantiate and execute objects of the new derived class. The ATM could execute transactions of the new type using the current code, because it executes all transactions identically.

As you learned earlier in the chapter, an abstract class like Transaction is one for which you never intend to instantiate objects. An abstract class simply declares common attributes and behaviors for its derived classes in an inheritance hierarchy. Class Transaction defines the concept of what it means to be a transaction that has an account number and executes. You may wonder why we bother to include pure virtual member function execute in class Transaction if execute lacks a concrete implementation. Conceptually, we include this member function because it’s the defining behavior of all transactions—executing. Technically, we must include member function execute in base class Transaction so that the ATM (or any other class) can polymorphically invoke each derived class’s overridden version of this function through a Transaction pointer or reference.

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

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