1.0 Introduction to ObjectOriented Programming
1.0 Introduction to ObjectOriented Programming
Since the 1980s the word 'object' has appeared in relation to programming languages, with
almost all languages developed since 1990 having object-oriented features. Some
languages have even had object-oriented features retro-fitted. It is widely accepted that
object-oriented programming is the most important and powerful way of creating software.
Classes
Objects
Classification
Polymorphism
Inheritance
An Object-Oriented Class
If we think of a real-world object, such as a television (as in Figure 1.1), it will have several
features and properties:
Page 1 of 17
A class should:
With a functional programming language (like C) we would have the component parts of the
television scattered everywhere and we would be responsible for making them work
correctly - there would be no case surrounding the electronic components.
Humans use class based descriptions all the time - what is a duck? (Think about this, we will
discuss it soon.)
States - (or data) are the values that the object has.
Methods - (or behaviour) are the ways in which the object can interact with its data,
the actions.
The notation used in Figure 1.2 on the right hand side is a Unified Modelling Language
(UML) representation of the Television class for object-oriented modelling and
programming.
Page 2 of 17
An instance of a class is called an object.
An Object
An object is an instance of a class. You could think of a class as the description of a
concept, and an object as the realisation of this description to create an independent
distinguishable entity. For example, in the case of the Television, the class is the set of
plans (or blueprints) for a generic television, whereas a television object is the realisation of
these plans into a real-world physical television. So there would be one set of plans (the
class), but there could be thousands of real-world televisions (objects).
Page 3 of 17
Encapsulation
The object-oriented paradigm encourages encapsulation. Encapsulation is used to hide the
mechanics of the object, allowing the actual implementation of the object to be hidden, so
that we don't need to understand how the object works. All we need to understand is the
interface that is provided for us.
You can think of this in the case of the Television class, where the functionality of the
television is hidden from us, but we are provided with a remote control, or set of controls
for interacting with the television, providing a high level of abstraction. So, as in Figure
1.4 there is no requirement to understand how the signal is decoded from the aerial and
converted into a picture to be displayed on the screen before you can use the television.
There is a sub-set of functionality that the user is allowed to call, termed the interface. In
the case of the television, this would be the functionality that we could use through the
remote control or buttons on the front of the television.
The full implemenation of a class is the sum of the public interface plus the private
implementation.
Page 4 of 17
Encapsulation is the term used to describe the way that the interface is separated from the
implementation. You can think of encapsulation as "data-hiding", allowing certain parts of
an object to be visible, while other parts remain hidden. This has advantages for both the
user and the programmer.
The programmer can change the implementation, but need not notify the user.
So, providing the programmer does not change the interface in any way, the user will be
unaware of any changes, except maybe a minor change in the actual functionality of the
application.
We can identify a level of 'hiding' of particular methods or states within a class using
the public, private and protected keywords:
Figure 1.5 shows encapsulation as it relates to the Television class. According to UML
notation private methods are denoted with a minus sign and public methods are denoted
with a plus sign. The private methods would be methods written that are part of the inner
workings of the television, but need not be understood by the user. For example, the user
would need to call the powerOn() method but the private displayPicture() method
would also be called, but internally as required, not directly by the user. This method is
therefore not added to the interface, but hidden internally in the implementation by using
the private keyword.
Page 5 of 17
Inheritance
If we have several descriptions with some commonality between these descriptions, we can
group the descriptions and their commonality using inheritance to provide a compact
representation of these descriptions. The object-oriented programming approach allows us
to group the commonalities and create classes that can describe their differences from other
classes.
Humans use this concept in categorising objects and descriptions. For example you may
have answered the question - "What is a duck?", with "a bird that swims", or even more
accurately, "a bird that swims, with webbed feet, and a bill instead of a beak". So we could
say that a Duck is a Bird that swims, so we could describe this as in Figure 1.6. This figure
illustrates the inheritance relationship between a Duck and a Bird. In effect we can say
that a Duck is a special type of Bird.
For example: if were to be given an unstructured group of descriptions such as Car, Saloon,
Estate, Van, Vehicle, Motorbike and Scooter, and asked to organise these descriptions by
their differences. You might say that a Saloon car is a Car but has a long boot, whereas an
Estate car is a car with a very large boot. Figure 1.7 shows an example of how we may
organise these descriptions using inheritance.
Page 6 of 17
Figure 1.7. The grouped set of classes.
One way to determine that you have organised your classes correctly is to check them using
the "IS-A" and "IS-A-PART-OF" relationship checks. It is easy to confuse objects within a
class and children of classes when you first begin programming with an OOP methodology.
So, to check the previous relationship between Car and Vehicle, we can see this in
Figure 1.9.
Page 7 of 17
The IS-A relationship describes the inheritance in the figure, where we can say, "A Car IS-A
Vehicle" and "A SaloonCar IS-A Car", so all relationships are correct. The IS-A-PART-OF
relationship describes the composition (or aggregation) of a class. So in the same figure
(Figure 1.9) we can say "An Engine IS-A-PART-OF a Vehicle", or "An Engine, Colour and
Wheels IS-A-PART-OF a Vehicle". This is the case even though an Engine is also a class!
where there could be many different descriptions of an Engine - petrol, diesel, 1.4, 2.0, 16
valve etc.
Inherit a behaviour and add further specialised behaviour - for example a Car IS
A Vehicle with the addition of four Wheel objects, Seats etc.
Inherit a behaviour and replace it - for example the SaloonCar class will inherit
from Car and provide a new "boot" implementation.
Cut down on the amount of code that needs to be written and debugged - for
example in this case only the differences are detailed, a SaloonCar is essentially
identical to the Car, with only the differences requiring description.
Polymorphism
When a class inherits from another class it inherits both the states and methods of that
class, so in the case of the Car class inheriting from the Vehicle class the Car class
inherits the methods of the Vehicle class, such as engineStart(), gearChange(),
lightsOn() etc. The Car class will also inherit the states of the Vehicle class, such
as isEngineOn, isLightsOn, numberWheels etc.
Page 8 of 17
Polymorphism means "multiple forms". In OOP these multiple forms refer to multiple forms
of the same method, where the exact same method name can be used in different classes,
or the same method name can be used in the same class with slightly different paramaters.
There are two forms of polymorphism, over-riding and over-loading.
Over-Riding
As discussed, a derived class inherits its methods from the base class. It may be necessary
to redefine an inherited method to provide specific behaviour for a derived class - and so
alter the implementation. So, over-riding is the term used to describe the situation where
the same method name is called on two different objects and each object responds
differently.
Over-riding allows different kinds of objects that share a common behaviour to be used in
code that only requires that common behaviour.
Consider the previous example of the Vehicle class diagram in Figure 1.7. In this case
Car inherits from Vehicle and from this class Car there are further derived classes
SaloonCar and EstateCar. If a draw()method is added to the Car class, that is
required to draw a picture of a generic vehicle. This method will not adequately draw an
estate car, or other child classes. Over-Riding allows us to write a specialised
draw() method for the EstateCar class - There is no need to write a new
draw() method for the SaloonCar class as the Car class provides a suitable enough
draw() method. All we have to do is write a new draw() method in the EstateCar class
with the exact same method name. So, Over-Riding allows:
A more straightforward API where we can call methods the same name, even
thought these methods have slightly different functionality.
A better level of abstraction, in that the implementation mechanics remain hidden.
Page 9 of 17
Over-Loading
Over-Loading is the second form of polymorphism. The same method name can be used,
but the number of parameters or the types of parameters can differ, allowing the correct
method to be chosen by the compiler. For example:
are two different methods that have the same name and the same number of parameters.
However, when we pass two String objects instead of two int variables then we expect
different functionality. When we add two int values we expect an intresult - for example 6 +
7 = 13. However, if we passed two String objects we would expect a result of "6" + "7"
= "67". In other words the strings should be concatenated.
The number of arguments can also determine which method should be run. For example:
channel()
channel(int x)
will provide different functionality where the first method may simply display the current
channel number, but the second method will set the channel number to the number passed.
Abstract Classes
An abstract class is a class that is incomplete, in that it describes a set of operations, but is
missing the actual implementation of these operations. Abstract classes:
Cannot be instantiated.
So, can only be used through inheritance.
For example: In the Vehicle class example previously the draw() method may be
defined as abstract as it is not really possible to draw a generic vehicle. By doing this we are
forcing all derived classes to write a draw() method if they are to be instantiated.
As discussed previously, a class is like a set of plans from which you can create objects. In
relation to this analogy, an abstract class is like a set of plans with some part of the plans
missing. E.g. it could be a car with no engine - you would not be able to make complete car
objects without the missing parts of the plan.
Page 10 of 17
Figure 1.11 illustrates this example. The draw() has been written in all of the classes and
has some functionality. The draw() in the Vehicle has been tagged as abstract and so
this class cannot be instantiated - i.e. we cannot create an object of the Vehicle class, as
it is incomplete. In Figure 1.11 the SaloonCar has no draw() method, but it does
inherit a draw() method from the parent Car class. Therefore, it is possible to create
objects of SaloonCar.
If we required we could also tag the draw() method as abstract in a derived class, for
example we could also have tagged the draw() as abstract in the Car class. This would
mean that you could not create an object of the Car class and would pass on
responsibility for implementing the draw() method to its children - see Figure 1.12.
Figure 1.12. The abstract draw() method in the Vehicle and Car classes.
Page 11 of 17
The Object-Oriented Design Model
One object-oriented methodology is based around the re-use of development modules and
components. As such, a new development model is required that takes this re-use into
account. The object-oriented model as shown in Figure 1.15 builds integration of existing
software modules into the system development. A database of reusable components
supplies the components for re-use. The object-oriented model starts with the formulation
and analysis of the problem. The design phase is followed by a survey of the component
library to see if any of the components can be re-used in the system development. If the
component is not available in the library then a new component must be developed,
involving formulation, analysis, coding and testing of the module. The new component is
added to the library and used to construct the new application.
This model aims to reduce costs by integrating existing modules into development. These
modules are usually of a higher quality as they have been tested in the field by other clients
and should have been debugged. The development time using this model should be lower as
there is less code to write.
Page 12 of 17
The object-oriented model should provide advantages over the other models, especially as
the library of components that is developed grows over time.
Task: If we were given the problem; “Write a program to implement a simple savings
account”… The account should allow deposits, withdrawals, interest and fees.
Page 13 of 17
Solution: The problem produces many concepts, such as bank account, deposit,
withdrawal, balance etc.. that are important to understand. An OO language allows the
programmer to bring these concepts right through to the coding step. The savings account
may be built with the properties of an account number and balance and with the methods of
deposit and withdrawal, in keeping with the concept of the bank account. This allows an
almost direct mapping between the design and the coding stages, allowing code that is easy
to read and understand (reducing maintenance and development costs).
OOP also allows software re-use! … The concept of this savings account should be
understood, independent of the rest of the problem. This general savings account will
certainly find re-use in some other financial problem.
So after discussion with the client, the following formulation could be achieved - Design a
banking system that contains both teller and ATM interaction with the rules:
currency converter
Page 14 of 17
Transaction (requires a cash card)
Lodgement (has an account number, an amount)
Withdrawal (has an account number, an amount)
Cheque ( is a withdrawal, has a payee, an amount)
Eurocheque (is a cheque, has a currency)
ATMs (accept cashcards, dispense cash)
Bank:
has a name
has accounts
has a base currency
has a sort code
Account:
has an owner
has a balance
has an account number
has a log of transactions
Deposit Account:
is an account
has a shared interest rate
Current Account:
is an account
has an overdraft limit
Transaction:
has an account
has a date
has a value
has a bank
has an account Number
has a number
Withdrawal:
is a transaction
Lodgement:
is a transaction
Page 15 of 17
Cheque:
is a withdrawal
has a payee
EuroCheque:
is a cheque
has a currency
CurrencyConverter:
Page 16 of 17
Figure 1.18. The Transaction class.
Page 17 of 17