Object Oriented Programming
Inheritance and
Polymorphism
Contents
Base classes and derived classes
Example a BankAccount class
Polymorphism and Object Oriented Programming
Abstract classes
Generic Programming
Polymorphism and OOP
Summary
Base classes and derived classes
Inheritance is a fundamental requirement of oriented
programming
It allows us to create new classes by refining existing classes
Essentially a derived class can inherit data members of a base
class
The behaviour of the derived class can be refined by
redefining base class member functions or adding new
member function
A key aspect of this is polymorphism where a classes
behaviour can be adapted at run-time
Base classes and derived classes
We can think of many examples in real life of how a
(base) class can be refined to a set of (derived)
classes
For example a Polygon class can be refined to be a
Quadrilateral which can be further refined to be a
Rectangle
We can think of these classes as following an IS-A
relationship
A Quadrilateral IS-A Polygon
A Rectangle IS-A Quadrilateral
Base classes and derived classes
Base class
Shape
Derived class
Triangle, Circle,
Rectangle
Account
Current, Deposit
Student
Undergraduate,
Postgaduate
Vehicle
Car, Truck, Bus
Filter
Low-pass, Band-pass,
High-pass
Example
a
BankAccount
class
An BankAccount base class models basic information
about a bank account
Account holder
Account number
Current balance
Basic functionality
Withdraw money
Deposit money
public class
{
private
private
private
BankAccount
int accountNumber;
string accountHolder;
int balance;
public BankAccount(int n,string name ,int b)
{
accountNumber = n;
accountHolder = name;
balance = b;
}
public int AccountNumber { // accountNumber property}
public string AccountHolder { // accounHolder property}
public int Balance { // balance property}
public void withdraw(int amount)
{
if (balance>amount)
balance-=amount;
}
public void deposit(int amount) { balance+=amount;}
}
Example a BankAccount class
We can consider refinements to our Account class
CurrentAccount
Can have an overdraft facility
No interest paid
DepositAccount
Pays interest on any balance
No overdraft facility
Example a BankAccount class
We will create our refined classes using inheritance from the
BankAccount base class
Classes CurrentAccount and DepositAccount inherit the basic
attributes (private members) of account
accountNumber
accountHolder
balance
Also, new attributes are added
overdraftFacility
interestRate
Example a BankAccount class
In order to implement the derived classes, we need to consider
private/public access between base and derived classes
public member functions of the base class become public
member functions of the derived class
private members of the base class cannot be accessed from
the derived class
Obvious otherwise encapsulation could be easily
broken by inheriting from the base class
Begs the question, how do we initialise derived class
objects?
Example a BankAccount class
Base class methods and properties are
accessed through the base keyword
base(.....) refers to the base class
constructor
base.aMethod(.....) refers to a method of the
base class
base.aProperty refers to a property of the
base class
class CurrentAccount : BankAccount
{
private int overdraftFacility;
public CurrentAccount(int n, string name, int b, int ov) : base(n, name, b)
{
overdraftFacility = ov;
}
public override void withdraw(int amount)
{
if (base.Balance - amount > -overdraftFacility)
base.Balance -= amount;
}
}
class DepositAccount : BankAccount
{
private float interestRate;
public DepositAccount(int n, string name, int b, float rate) : base( n, name,b)
{ interestRate = rate; }
float calcInterest()
{
float interest = base.Balance * interestRate;
base.Balance += (int)(interest);
return interest;
}
}
Example a BankAccount class
CurrentAccount
DepositAccount
accountNumber
accountHolder
balance
accountNumber
accountHolder
balance
deposit()
withdraw()
deposit()
withdraw()
overdraftFacility
interestRate
withdraw()
calcInterest()
Example a BankAccount class
We can see that in both derived classes we need to access the
balance instance field
We can do this directly (without using a public method or
property) by making balance a protected member of the base class
A protected class member is one that can be accessed by public
member functions of the class as well as public member functions
of any derived class
Its half way between private and public
Encapsulation is then broken for classes in the inheritance
hierarchy and thus must be used where performance issues are
critical
Example a BankAccount class
Class member
Can be accessed from
private
public member
functions of same class
protected
public member
functions of same class
and derived classes
public
Anywhere
public class BankAccount
{
private int accountNumber;
private string accountHolder;
protected int balance;
public BankAccount(int n,string name ,int b)
{
accountNumber = n;
accountHolder = name;
balance = b;
}
public int AccountNumber { // accountNumber property}
public string AccountHolder { // accounHolder property}
public int Balance { // balance property}
public void withdraw(int amount)
{
if (balance>amount)
balance-=amount;
}
public void deposit(int amount) { balance+=amount;}
}
class CurrentAccount : BankAccount
{
private int overdraftFacility;
public CurrentAccount(int n, string name, int b, int ov) : base(n, name, b)
{
overdraftFacility = ov;
}
public override void withdraw(int amount)
{
if (balance - amount > -overdraftFacility)
balance -= amount;
}
// balance is protected
}
class DepositAccount : BankAccount
{
private float interestRate;
public DepositAccount(int n, string name, int b, float rate) : base( n, name,b)
{ interestRate = rate; }
float calcInterest()
{
float interest = balance * interestRate;
balance += (int)(interest);
return interest;
}
}
Polymorphism and Object
Oriented Programming
Polymorphism is the key concept in object
oriented programming
Polymorphism literally means many forms
Essentially we are able to get many different
types of object behaviour from a single
reference type
This enables us to write easily extensible
applications
Polymorphism and Object
Oriented Programming
For example in a computer game that simulates the
movement of animals we can send move
commands to different types of animal
We send the commands via an animal reference
which is the base class for the different animal types
But each type behaves differently once it receives
the command
Such an approach leads to a readily extendable
application
Polymorphism and Object
Oriented Programming
Application
animal
Move
Polymorphism and Object
Oriented Programming
Polymorphism is implemented through
references to objects
We can assign base class object references
to any derived class object
BankAccount acc1 = new CurrentAccount(12345, "John Smith", 1000, 500);
BankAccount acc2 = new DepositAccount(54321, "Bill Jones", 2000, 5.0);
Polymorphism and Object
Oriented Programming
CurrentAccount
acc1
12345
John Smith
1000
deposit()
withdraw()
500
withdraw()
Polymorphism and Object
Oriented Programming
DepositAccount
acc2
54321
Bill Jones
2000
deposit()
withdraw()
5.0
calcInterest()
Polymorphism and Object
Oriented Programming
We can see that in the case of the reference
to a CurrentAccountObject object, method
withdraw() is overidden in the derived class
The question is, which one is called at
runtime?
public class BankAccountTest
{
static void Main(string[] args)
{
BankAccount acc1 = new CurrentAccount(12345, "John Smith,1000, 500);
acc1.withdraw(250);
}
}
// Which withdraw()?
Polymorphism and Object
Oriented Programming
CurrentAccount
acc1
accountNumber
accountHolder
balance
deposit()
withdraw()
overdraftFacility
withdraw()
Which one
is called?
Polymorphism and Object
Oriented Programming
Clearly the behaviour of the object to the withdraw
message is important
The derived class behaviour takes into account the
overdraft facility
We must look at the definitions of the withdraw() method
in the base and derived classes
The base class withdraw() method is overridden by the
derived class method if the base class method is
declared as virtual and the derived class method is
declared as override
Polymorphism and Object
Oriented Programming
public class BankAccount
{
//
public virtual void withdraw(int amount)
{
if (balance - amount > -overdraftFacility)
balance -= amount;
}
}
public class CurrentAccount : BankAccount
{
private int overdraftFacility;
public CurrentAccount(n, name, b) {}
public override void withdraw(int amount)
{
if (balance - amount > -overdraftFacility)
balance -= amount;
}
}
Polymorphism and Object
Oriented Programming
Because withdraw() in the derived class is
declared as an override function of the virtual
function in the base class, the correct behaviour is
obtained
public class BankAccountTest
{
static void Main(string[] args)
{
BankAccount acc1 = new CurrentAccount(12345, "John Smith,1000, 500);
acc1.withdraw(250);
}
}
// Calls the CurrentAccount withdraw() method
Polymorphism and Object
Oriented Programming
In Java, polymorphism (overriding the base class
implementation) is the default behaviour
In C++, the virtual keyword is used but no override
keyword
C# also has a keyword sealed for a base class
method which cant be overriden
Methods can also be declared override and
sealed indicating that they override a base class
method but cant themselves be overriden
Abstract classes
In our example classes, the withdraw()
method of our BankAccount was declared as
a virtual function
We were able to provide a sensible
implementation of this function
This implementation could be regarded
as default behaviour if the function was
not overridden in derived classes
Abstract classes
If the method called cant be resolved in the
derived class, it is delegated back to the
default base class method
public class BankAccountTest
{
static void Main(string[] args)
{
BankAccount acc1 = new CurrentAccount(12345, "John Smith,1000, 500);
acc1.withdraw(250);
// Calls the CurrentAccount withdraw() method
BankAccount acc2 = new DepositAccount(54321, Bill Jones,2000, 5.0);
acc2.withdraw(100);
}
}
// Calls the BankAccount withdraw() method
Abstract classes
Abstract classes arise when there is no sensible
implementation of the virtual functions in the base
class
Base class virtual functions are always overridden
by derived class implementations
In this case, we simply declare the virtual function as
abstract but provide no implementation
A class containing at least one abstract function
must be declared an abstract class
Abstract classes
As an example, suppose we wanted to design a hierarchy
of shape classes for a computer graphics application
Shape is an abstract concept
There is no sensible way we can implement functions
to draw a shape or compute the area of a shape
It is natural to make such functions abstract
We can derive concrete classes from shape and
provide implementations in the override functions
Abstract classes
public abstract class Shape
{
private int xpos;
private int ypos;
public abstract void draw();
public abstract double area();
public virtual void move(int x, int y)
{
xpos+=x;
ypos+=y;
}
}
Abstract classes
public class Square : Shape
{
private int side;
public Square(int s) {side=s;}
public override void draw() { }
public override double area() { return side*side; }
}
public class Circle : Shape
{
private int radius;
public Circle(int r) { radius = r; }
public override void draw() { }
public override double area() { return System.Math.PI*radius*radius;}
}
Abstract classes
We cant create Shape objects but we can
declare Shape references and assign them to
derived class objects
using System;
class ShapeTest
{
static void Main(string[] args)
{
Shape sq = new Square(10);
Shape c = new Circle(5);
System.Console.WriteLine("Area of square= " + sq.area());
System.Console.WriteLine("Area of circle= " + c.area());
}
}
Abstract classes
We can regard abstract classes as a glue which
binds related classes together and where we dont
have to worry about implementational details
They just have to present a common interface
Shape
Circle
Square
draw()
area()
Triangle
.......
Generic programming
Generic programming refers to performing
operations on different types using a single piece
of code
Examples include the application of searching
and sorting algorithms to different data types
In Java, this is done using polymorphism and the
fact that all types are ultimately derived from a
superclass object
In C++ it is normally done using templates
C# provides both mechanisms for generic
programming
We will look at an example of generic searching
using polymorphism
Generic programming
Suppose we want a generic search algorithm to
search for any kind of object in an array
Class object provides an Equals() method to test
whether one object is equal to another
Simply checks if the 2 object references point
to the same area of memory
Not very useful in practice
We need to provide an Equals() method in the
class of the object we are searching for
Polymorphism does the rest!
Generic Programming
In the following example we are searching
for a BankAccount object in an array
The search is based on the account
number
Class SearchAlg provides a linearSearch
method which carries out the search
We have provided an implementation of
Equals() in class BankAccount which
overrides the Equals() method in object
public class
{
private
private
private
BankAccount
int accountNumber;
string accountHolder;
int balance;
public BankAccount(int n,string name ,int b)
{
accountNumber = n;
accountHolder = name;
balance = b;
}
public int AccountNumber { // accountNumber property}
public string AccountHolder { // accounHolder property}
public int Balance { // balance property}
public void withdraw(int amount)
{
if (balance>amount)
balance-=amount;
}
public void deposit(int amount) { balance+=amount;}
public override bool Equals(object obj)
{
BankAccount b = (BankAccount) obj;
return (accountNumber==b.accountNumber);
}
}
Generic Programming
using System;
public class SearchAlg
{
public static int linearSearch(object[] a, object b)
{
int n=a.Length;
for (int i=0; i<n; i++)
{
if (a[i].Equals(b))
return i;
}
return -1;
}
}
Generic Programming
using System;
public class BankAccountTest
{
static void Main(string[] args)
{
BankAccount[] b = new BankAccount[3];
b[0]=new BankAccount(12345, "John Smith",100);
b[1]=new BankAccount(13579, "Bill Jones",200);
b[2]=new BankAccount(87654, "Paul Brown",300);
BankAccount bt=new BankAccount(13579, "JonesB", 700);
int index=SearchAlg.linearSearch(b,bt);
Console.WriteLine("Acount found at index " + index);
}
}
Polymorphism and OOP
Polymorphism is a key feature of object oriented
programming
Complex systems are able to be easily extended
The extendibility is provided by defining new classes
within an inheritance hierarchy
Objects of these new classes are accessed through a base
class reference
These objects add new behaviours to the system through
a common interface to the application (the base class
virtual functions)
Polymorphism and OOP
For example we could extend the list of animals
to which we can send move messages in our
video game application
Each animal is responsible for its own
movement code which can easily plug-in to
the main application
Thus the application is easily extended with
minimal changes to the main application code
Polymorphism and OOP
animal
Move
Summary
We have looked at how we can extend existing classes through the
idea of inheritance
We have seen how, by accessing derived classes through a base class
pointer, object behaviour is determined at run time through
polymorphism
We have looked at abstract classes where there is no obvious
implementation of base class virtual methods
These methods are always overriden by derived class methods
We have looked at the significance of polymorphism in object
orientation
Object oriented applications are easily extended with additional
code mainly confined to new derived classes