UNIT 1 -
PROGRAMMING
LECTURE 9 – OBJECT ORIENTED PROGRAMMING PART 3
PLAN
Inheritance
Base class
Override method
Polymorphism
Abstract class
Unit 1 - Programming / Lecture 8 – Object oriented programming Part 2 2
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
o The behaviour of the derived class can be refined by redefining base class
member functions or adding new member function
o 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
o A Quadrilateral IS-A Polygon
o A Rectangle IS-A Quadrilateral
BASE CLASSES AND DERIVED CLASSES
Base class Derived class
Shape Triangle, Circle,
Rectangle
Bank 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
o Account holder
o Account number
o Current balance
Basic functionality
o Withdraw money
o Deposit money
public class BankAccount
{
private int accountNumber;
private string accountHolder;
private 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
o CurrentAccount
• Can have an overdraft facility
• No interest paid
o 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
o accountNumber
o accountHolder
o balance
Also, new attributes are added
o overdraftFacility
o interestRate
EXAMPLE – A BANKACCOUNT CLASS
In order to implement the derived classes, we need to consider
private/public access between base and derived classes
o public member functions of the base class become public member functions of
the derived class
o 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
o base(.....) refers to the base class constructor
o base.aMethod(.....) refers to a method of the base class
o 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
DepositAccount
accountNumber accountNumber
accountHolder accountHolder
balance balance
CurrentAccount
deposit() deposit()
withdraw() 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
o Its half way between private and public
o 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 is protected
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 = 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
o 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
o But each type behaves differently once it receives the command
o 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
12345
acc1 John Smith
1000
deposit()
withdraw()
500
withdraw()
POLYMORPHISM AND OBJECT ORIENTED
PROGRAMMING DepositAccount
54321
acc2 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()
Which one
is called?
overdraftFacility
withdraw()
POLYMORPHISM AND OBJECT ORIENTED
PROGRAMMING
Clearly the behaviour of the object to the ‘withdraw’ message is
important
o 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
o 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 can’t be
overriden
o Methods can also be declared override and sealed indicating that they override
a base class method but can’t themselves be overriden
ABSTRACT CLASSES
In our example classes, the withdraw() method of our BankAccount was
declared as a virtual function
o We were able to provide a sensible implementation of this function
o This implementation could be regarded as default behaviour if the function was
not overridden in derived classes
ABSTRACT CLASSES
If the method called can’t 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
o 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
o 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
o There is no sensible way we can implement functions to draw a shape or
compute the area of a shape
o It is natural to make such functions abstract
o 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 can’t 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());
}
}