object-oriented programming in c++ lecture 6 inheritance
TRANSCRIPT
Object-Oriented Programming in C++
Lecture 6
Inheritance
IntroductionLast lecture we
•introduced pointer variable
•discussed dynamic memory– creating objects using new– deleting objects
This lecture we will
•review the concept of inheritance
•discuss how to implement inheritance in C++
Class hierarchies• inheritance can be used
to describe families of related classes
• the common attributes and functions are described in a superclass, or base class
• subclasses (derived classes) can extend or modify the functionality of a superclass
• C++ allows both public and private inheritance
Animal
Mammal Fish
Cat Dog
Public inheritance• public inheritance allows the subclass to have
access to all the public member variables and functions of the superclass
• if we want the subclass to access a member but keep encapsulation, we can use the access modifier protected
• protected modifiers can be access from subclasses, but not from outside the class
• subclasses can have new member variables and methods
• and override (provide new implementations of) superclass methods
• a subclass can overload existing superclass methods– similar to providing new methods
Account base class
• suppose we wanted to refactor our Account system• we have put a lot of methods into a single class
– does every account need all of them
• let's define a hierarchy of more specialised accounts• the base class will be account• it will hold the account balance, and have methods to
– deposit money– withdraw money– return the balance
Savings account• a more specialised account could be a savings
account• a savings account pays interest every month• account holders are not allowed to go
overdrawn• in addition to the account functionality, a
savings account could have methods to – get the interest rate– calculate and add the interest
• this account needs to hold the interest rate• it also needs to redefine the withdraw function
– the Account class didn't specify any limits on withdrawal
More accounts• we could also define a current account
– it can accept and issue cheques– but it doesn't pay any interest– it does have an overdraft limit
• the account holder is fined if the account goes over the limit
• it would also be nice to have a super savings account– this is a savings account with tiered interest rates– the interest rate is higher if the balance is greater
than a certain amount– however, you are not allowed to withdraw more
than £50 pounds at a time from the account
Header files
• each class in the hierarchy could have its own header file
• need to #include the header file of the base class– will get multiple inclusions
• or put all the class declarations in the same header file
• in this example we will declare the base class inline – and declare the other classes with prototypes for the
functions
Account.h
#ifndef ACCOUNT_H#define ACCOUNT_H#include <iostream>#include "Cheque.h"using namespace std;
class Account {protected:double balance;
public: Account(double initialBalance = 0.0): balance(initialBalance){cout << "Account constructor";}double getBalance() const { return balance; }void deposit(double amount) { balance += amount; } void withdraw(double & amount) { cout << "Account version of withdraw" << endl; balance -= amount;
}};
Account.h (continued)class SavingsAccount: public Account {protected:
double interestRate;public:SavingsAccount(double initialBalance, double rate);
double getInterestRate() const { return interestRate; } // new methodvoid addInterest(); // new methodvoid withdraw(double & amount); // redefinition - we won't allow account to be overdrawn
};
Account.h (continued)
class SuperSavingsAccount : public SavingsAccount {protected:
double bonusBalance;double bonusInterestRate;
public:SuperSavingsAccount(double initialBalance, double rate, double bBalance, double bRate);
double getBonusRate(); // new methodvoid addInterest(); // redefinitionvoid withdraw(double & amount); // redefinition - withdrawal limit is 50
};
Account.h (continued)
class CurrentAccount : public Account {private:
double fine;double overdraftLimit;
public:CurrentAccount(double initialBalance, double f, double limit);void deposit(const Cheque & cheque );void withdraw(double & amount);Cheque * issueCheque(double & amount);
};
#endif
Derived class constructor
SavingsAccount::SavingsAccount(double initialBalance, double rate)
: Account(initialBalance), interestRate(rate) {}•calls the Account constructor with appropriate parameters
– the balance will be initiased
•then initialise this class's member variable – interest rate
Sub-sub class constructor
SuperSavingsAccount::SuperSavingsAccount(double initialBalance, double rate, double bBalance, double bRate): SavingsAccount(initialBalance, rate), bonusBalance(bBalance), bonusInterestRate(bRate) {cout << "SuperSavingsAccount constructor " << endl;}
•just calls the constructor of the immediate parent (SavingsAccount)•it will call the constructor of its parent…
Order of construction
• the base class constructor is run first
• followed by its child
• and so on down to this class
Output:Account constructorSavingsAccount constructorSuperSavingsAccount constructor
Methods• all the public methods of the base class, plus its
superclasses, are available to pubicly derived classesSuperSavingsAccount acc2(50, 5, 100, 10);acc2.deposit(100);cout << "Account balance " << acc2.getBalance() << endl;amount = 500;acc2.withdraw(amount);cout << amount << " withdrawn. Account balance: " << acc2.getBalance() << endl;acc2.addInterest();cout << "Account balance " << acc2.getBalance() << endl;cout << "Bonus rate " << acc2.getBonusRate() << endl;
Methods
• if a base class method is overridden in the derived class, the overridden version is used
• make sure the method signatures are the same–otherwise you are overloading the method, not overriding
• (we will talk about polymorphism next lecture)• Output:
Account constructorSavingsAccount constructorSuperSavingsAccount constructorAccount balance 150SupersavingsSavings version of withdraw
Using base class methods
• derived classes can still access overridden base class methods
• by calling the method with the base class name qualifiervoid SuperSavingsAccount::addInterest() {
// call superclass version SavingsAccount::addInterest();
if (balance >= bonusBalance) {balance *= (1 +
bonusInterestRate/100.0);}
}
Multiple inheritance
• multiple inheritance is allowed in C++
• unlike Java and C#– allowed to have
multiple interface• this can cause
problems if two sides of the inheritance family have a common ancestor
Account
SavingsAccount CurrentAccount
CurrentSavingsAccount
Multiple Inheritance• what if we wanted to create a CurrentSavings
account?• we would call the Account constructor twice• and end up with two copies of the balance
member variable– need to inherit with keyword virtual
• we can also encounter problems if two different super classes have attributes with the same name– qualify them with the class name
Private inheritance
• unlike Java, C++ also allows private inheritance
• the derived class can still access the public and protected members of the base class
• but they are not visible outside the class• useful if you want to adapt an existing class to
use a new interface– different signatures for the public methods– use appropriate methods of the superclass
• Class Adapter pattern
Private inheritance
class AdaptedAccount : private Account {public:
AdaptedAccount(double initialBalance) : Account(initialBalance) {}double getMoney() { return getBalance(); }void putInMoney(double amount) { deposit(amount); }void takeOutMoney(double & amount) { withdraw(amount);}
};
SummaryIn this lecture we have:
•reviewed the concept of inheritance
•discussed how to implement inheritance in C++In the next lecture we will;•discuss polymorphism