Object Oriented Programming is a programming methodology that looks at the program in terms of smaller self contained mini programs (objects) that each have their own name, data and logic, and that interact with one another to form a whole application.


OOP is intended to make thinking about programming closer to thinking about the real world, where an object's attributes and behaviours are bundled together. For example, the following represents a real world scenario of 2 people, viewing their shared bank account with one also interacting with a shopping cart.



This could be represented by considering each individual item as an object, with their own attributes and behaviours:


OOP utilises a technique of defining a construct known as a class which acts like a template / cookie cutter to create objects. A class is an advanced form of an abstract data type (as opposed to the basic/primitive data types,  such as an int or char) that allows the creation of objects that behave in a similar manner but have their own individual characteristics.


This is in contrast to Procedural programming that basically looks at the program as a long (procedural) list, with all the data / variables defined in one place and all the logic in another. As procedural styled programs grew, they became difficult to manage which led to the uptake of OOP.


The process of bundling data with logic, is referred to as encapsulation, which is one of the fundamental features of OOP:

  1. Abstraction
  2. Encapsulation
  3. Inheritance
  4. Polymorphism

The idea is to take advantage of these features to promote code reuse whilst decreasing code maintenance.


Abstraction is the process of describing the general concept of an object without defining its specific details.


For example, we all understand what a motorbike is and your idea may be slightly different to someone else's (they might think it is red, has a specific engine size, or manufacturer), but in general terms you understand the concept of a motorbike because you've seen enough motorbikes and can abstract the essential details of a motorbike without having to go into too much detail.



We know that a motorbike has two wheels, handlebars and an engine, i.e. we know its prerequisites, the bare minimum that make this a motorbike.


We also know that a motorbike doesn't have a foot or branches so we can forget about those things since they have nothing to do with a motorbike.


Therefore, abstraction focuses on the common essential qualities of an object rather than any specific example.


Abstraction is at the very core of OOP, since it is this concept that allows us to create classes and from there to create objects.


We can therefore create a single class that can create many objects based on that class, with its common abstracted qualities.


This allows us to focus on what an object should have, specific to the application's requirements and the context.

Class Diagram

A UML (Unified Modelling Language) class diagram is used to provide a representation of the three main aspects of a class:



The top section contains the Name of the class

The middle section contains the Attributes of the class

The lower section contains the Methods of the class


The attributes and methods are referred to as the Members of the class.


The following symbols / annotations are applied before members to define their visibility:

+ Public
- Private
# Protected
~ Package
/ Derived
Underline Static


Attributes are the properties (aka data or variables) that represent the current state of the object.



For example, there are many people, so to describe one particular (instance of a) person, we might use their name, e.g. David. If further granularity is required, for example if there were more than one person whose name was David, we might then use further information about that person such as their age, or where they live, etc.


These variables are specific to that instance of the object.


Data stored within an object represents the state of the object.


In OO terminology, an object's data is referred to as its attributes.


An object's behaviours define the things an object can do.



For example, a person can walk, talk, eat, etc. These are all activities or behaviours that a person can perform or carry out, usually upon the data available to it. e.g. if a person object was instructed to walk, it might need to know in what direction or for how long, using the information available from the variables it has access to, i.e. its attributes.


In OO terminology, behaviours are referred to as methods.


Methods are akin to functions in general programming terminology.


Methods may alter the state of an object (setter) or simply provide ways of accessing it (getter).


Abstract data type, used to create objects.


Akin to a blueprint or a cookie cutter.


A class can be considered as a plan of how to make an object. And from one class, you can create multiple objects.


Once a class has been declared, an object can come into being (that is, become instantiated) by declaring a new identifier against the class (data type).


The class declares an object's attributes and methods.



Has three elements:

  • Identity(aka name, or type)
    • A descriptor / label for the object
      • e.g. Motorbike, Computer, Person
  • Data(aka properties, or atributes)
    • Attributes that describe the object
      • e.g.: Make, Model, Height, Age
  • Logic( aka Methods, Operations, or Behaviours)
    • Behaviour that it performs
      • e.g.: Accelerate, Wheelie, Calculate, Talk


Objects are created by declaring a class, and then using that class by defining (zero or more, where possible, of) its attributes - this process is known as instantiation.



Each object is an instance of a class, that has it's own attributes (data) and behaviours (methods) that are called upon by the object's interface (i.e. its inputs / outputs), which strictly control (according to its own rules) how its data is sent and received.


We can create many objects of the "Person" class and each can have their own name. attributes and behaviours.


They are self contained entities, that have:


  • Identity
    • Separate from other objects
      • e.g. a Dog has different breeds, or is called different names
  • Attributes
    • Information that describes their current state
      • e.g a Glass can be full or empty
      • e.g. a Door can be red or blue
  • Behaviour
    • Things they can do
      • e.g. a Car can accelerate, or brake

To identify an object, perhaps think:

  • Is the word a noun?
  • Can you put the word "a", "an" or  "the" in front of it?


Objects don't have to be tangible, physical or visible items - e.g. a bank account, time.


An object is also referred to as a concrete instance of a class.


Encapsulation is the process of combining attributes and methods into a single named entity.



Different levels of visibility can be applied to a class’s members to allow other objects to interact with it at an appropriate level.


Only the absolute bare minimum should be visible to external objects. This visibility is controlled by applying specific access levels to the class’s individual members.


Only public declared methods should be able to be seen and utilised by external objects.


It is these public declared methods that are considered as the class’s interface.



In this example the other Object can only invoke the public behaviours (in green) and is denied access to the attributes and private behaviours (in red). All of its attributes are enclosed within its methods and may only be accessed and changed by it methods. For instance in the real world, you don't have to know about the inner workings of the engine, you just have to twist the throttle to accelerate.


Any invoking object should not care how the requested object's methods are implemented, all they should care about is presenting the required information via a message (twist throttle) to the object’s public interface (accelerate) in the correct format, so that it can receive an expected return or action (increased speed).


Access to an object’s attributes should only be controlled by the object itself, and no other object should directly change an attribute of another object.


This concept is known as data hiding.


This is akin to the black box model. We don’t care what goes on inside as long as we get what we want from it, providing we supply the correct information to it.


So as long as the interface stays the same, the internal methods of the object can be changed or improved as/if required.


Reduces complexity and dependencies, so that a change in one place won't require multiple changes elsewhere.


Encapsulation not only provides a convenient way of treating an object as a single entity, but it also provides protection of the object by controlling what parts of the object are visible outside of the object.


This visibility is specifically controlled by access specifiers that define the level of visibility:

  • Public
    • Public members are accessible any place the object is visible
    • Public methods should be the only way to change an object’s attributes
    • Public members make up an object’s public interface
  • Private
    • Private members are accessible only from other members of the same class
      • i.e. once instantiated, only that object
  • Protected
    • Protected members are accessible from other members of the same class and to members of derived classes derived
      • i.e. a child class can also access the protected members of the parent


In this diagram, the red bordered otherObject only has access to the Public members of the Motorbike class. However, the derivedObject (which is intended to represent a child class of the parent class), not only has access to the Public members of the Motorbike class, but it also has access to the Protected members. The Private members of the Motorbike class remain accessible only by itself.


Generally, the default access to a class is (and should be) private, even if not explicitly stated.


Since we only want the object itself to be able to modify itself, we only allow the absolute bare minimum (that is required for the program to work) to be seen outside of the object.


All of an object’s attributes can and should only be modified by its own methods, and should therefore never be made public.


However, we make certain methods of an object public, to allow another object to invoke a change in the called object, by sending a message. The called object can then act upon that message and use its own methods to modify its attributes, thus keeping all behaviour under direct control of the messaged object itself.


Therefore, access specifiers provide protection of an object up to its public interface.


By making members Private, it forces other objects (and perhaps other programmers looking at your code) to utilise the Public methods of the object to access its attributes.



Thus allowing the interface of the class to be separated from the implementation, which is Privately taken care of inside the class, akin to a black box!


Messages are the communication mechanism between objects.


Messages enable one object to invoke an action (method) in another object.


Messages comprise of three components:

  1. The object being addressed
  2. The method to perform
  3. Any parameters required by the method


In this example, the driverObject is invoking the Motorbike's public accelerate method, with a parameter of 160 (e.g. to indicate the desired speed), as indicted by the purple coloured items.


The driver object has not directly changed the state of the object (in this case the speed), but has requested that the object utilises its own method to make the desired effect.

Interface Vs Implementation

The separation of a class's interface against its implementation is the core principle behind encapsulation and data hiding, ensuring that only the object itself control its own actions.


A class declaration combines the external interface (its non-private methods) with an implementation of that interface (the code that carries out the behaviour).


The interface defines a class's visibility to others.


  • Interface defines what an object can do, but doesn't actually do it
  • Implementation carries out the operation declared in the interface
  • The class design specifies the interfaces to enable an object to be instantiated and operated properly
  • The Interface should completely describe how users of the class interact with the class
  • The behaviour of an object must be invoked by a message using one of the provided interfaces
  • An object's attributes and behaviour is controlled by sending messages to the object
  • Messages consist of the target object's name, the desired behaviour to use (i.e. the method) and any parameters required by the behaviour


For example, let's take the example of increasing a motorbike's speed.


The rider doesn't care about the internal working they just want to increase the speed and so they twist the throttle to get the desired behaviour.


The throttle is the interface between the rider (the calling/invoking object) and the engine (the called object).


In this case, the message would be Motorbike.setSpeed(66); This is the interface.


Internally, the engine of the bike is doing all manner of things, e.g. supplying fuel from the petrol tank to the injectors, the injectors electronics controlling the amount of fuel supplied to the combustion chamber, the spark plugs igniting the fuel mix at the right time, opening the valves to exhaust the spent fuel, etc.


All of these actions are separated from the rider, who just wants to go faster. We don't want him to do any of the internal (private) methods, as this could have disastrous effects!


We therefore separate interface from implementation.

Accessors & Mutators

For data hiding to work, all attributes must be private and must never be part of the external interface.


Making as much of a class private as possible protects the class from unwanted changes/effects, and is essential to encapsulation. However being completely private would be useless because we need to set and get its attributes and potentially do something with them.


Seeing we want the protection of encapsulation, we need a mechanism that will allow us to set and get an object's attributes, and this is achieved by the use of setter and getter methods - or more formally: Mutators and Accessors.


By providing setters and getters, control of an object's attributes still remain with the object, but allows other objects to access its attributes by sending a message to its public methods (i.e. its interface).


In this diagram, the setSpeed public method is used to set the speed attributes of the Motorbike object. But being able to set the speed is a bit like have a throttle and no speedo, so we need another public method to get the speed, getSpeed, and similarly for the other attributes of the object.



  • If an object wants an attribute, a method is provided to return the attribute: a getter
  • The value of the attribute is provided by invoking that getter method
  • Similarly, setters are used to set an object's attribute value
  • The object that contains the attributes, retains control of the attribute


A variable does not exist until it is declared.


When the area of code in which it was declared exits, the variable ceases to exist. Its contents are lost.


The scope of a variable is therefore the validity of that variable within the location in which it was declared.


Sometimes this is also referred to as the duration of which the variable is valid, since a variable can be thought of as having a lifetime in which it exists.


The duration of a variable definition, and the extent to which it is accessible from other places, is called the variable’s scope.


Global scope refers to the validity of variables that are declared in the main body of the program outside of all functions, including main(), and is valid throughout the entire program. It is generally considered not good practice to declare globally scoped variables.


Local scope refers to validity of variables that are declared within an enclosing code block’s curly braces { }.


Locally scoped variables can only be used within their declared block and do not exist outside of their block.


Scope is delineated by curly braces { }



In this example, count belongs to method1 and is only accessible by method1. It is inaccessible by method2, which has no idea that it even exists:

public class Number {

	public method1() {
		int count ; //only valid within method1

	public method2() { //method2 is unaware of count in method1



In this example, method1 and method2 have their own copies of count, independent and inaccessible to each other:

public class Number {

	public method1() { //unaware of count in method2
		int count ; //only valid within method1

	public method2() { //unaware of count in method1
		int count ; //only valid within method2



Object scope

Object scope is used when an attribute needs to be shared by more than one method within the same object.


In this example, count is declared outside the scope of method1 and method2, but within scope of the class and is therefore available to all methods within the class. All methods use the same (and only) copy of count for the object:

public class Number {

	int count ; //available to all methods

	public method1() {
		count = 1 ; //assigning a value to count within method1

	public method2() {
		count = 2 ; //now assigning a new value to count within method2



In this example, count is declared outside the scope of the methods, but then also within each method, which provides three separate memory locations all with the name count individual to their context:

public class Number {

	int count ;

	public method1() {
		int count ; //count belongs to method1

	public method2() {
		int count ; //count belongs to method2

		this.count = 5 ; //use the "this" keyword to refer to the object variable count

*Note: the keyword this is a reference to the current object



Class scope

It is also possible to share an attribute, by making is static:

public class Number {

	static int count ; //this attribute is allocated a single memory location
			   //shared by all objects instantiated by the class

	public method1() {


*Note: potential pitfall, when one object instantiated by the class changes the value of count, it would be changed for all other instances of the object using count


Process of creating a new class from an existing class.


New class is know as the Derived, or Child or Subclass.


Existing class from which it was derived from is know as the Base, or Parent or Superclass.



*Note: In UML, Inheritance is shown as a large blank arrow head


Promotes code reuse and reduces code size.


Allows us to identify some shared members between objects


Overriding Parent methods for specific Child behaviour


Identify commonality, put into Parent, then let Child classes inherit


This technique implements what is referred to as the "Is-A" relationship.


a car is a vehicle

a Ferrari is a car

Therefore a Ferrari is also a vehicle


The Child class inherits the Parent's methods as follows:

Access by: Public Private Protected
Same class Yes Yes Yes
Derived class Yes Yes No
External class Yes No No


Public inheritance provides the Parent's Public and Protected methods to the Child (as its own Public and Protected methods) but not its Private methods, these should be accessed using calls to the Parent's Public methods.


Protected inheritance provides the Parent's Public and Protected members as Protected members in the Child.


Private inheritance provides the Parent's Public and Protected members as Private members in the Child.


A simple C++ code example:

#include <iostream>
using namespace std;

//define a Parent Abstract class - this is not called directly, but used by the derived classes
class Motorbike {
		int speed; //declare an attribute to be inherited
		void setSpeed(int a) { //define the public interface
			speed = a ;

class Ducati: public Motorbike { //define a Child Concrete class
		void getSpeed()
			{cout << "Here's a Ducati Panigale Motorbike going: " << speed << "mph..."<< endl ; }

class Yamaha: public Motorbike { //define a Child Concrete class
		void saySpeed()
			{cout << "This Yamaha Enduro Motorbike goes: " << speed << "mph, off road!" << endl ; }

int main() {
	Ducati panigale ; //declare an instance of the (ADT) class Ducati, called panigale
	panigale.setSpeed(129); //use the public method inherited from the Motorbike Parent Abstract class
	panigale.getSpeed(); //use the public method in the Child to display the previously set value

	Yamaha enduro ;

	return 0;

Here, the two subclasses (Ducati and Yamaha) use the Parent Motorbike class. This Parent class is never called directly, but just acts to provide similar qualities (members) to the derived classes, in this case the ability to set the int speed. The Child classes then use their own methods unique for their own behaviour, in this case their public methods of getSpeed and saySpeed (just using different names to show they are different).


From the Greek  meaning "Many Forms".


In OOP terms, this means that a called method can provide different behaviours, depending on the object calling it.


"single interface, different implementation"


A simple example often cited is the plus sign + which is often overloaded to make it behave in the correct manner according to the context in which its used. For example, sending two integers will make it behave like addition, whereas if two strings were sent, it would act like concatenation:


If a = 5 and b = 7 then a + b = 12


If a = "Hello, " and b = "World!" then a + b = "Hello, World!"


More specialised methods can be applied within the inherited (child) class, that enable different behaviour. This is referred to as over-riding the method of the superclass (write it again). Basically, we can use all the useful members of the Parent, but over-ride to provide a different behaviour when required.


As another example, given a base class shape, polymorphism enables the programmer to define different area methods for any number of derived classes, such as circles, rectangles and triangles. No matter what shape an object is, applying the area method (redefined within each child) to it will return the correct results.


A great example from: Faye Williams

In a room stands a mouse, a cat and a dog. From the far corner of the room, a speaker emits the sudden sound of a balloon popping. The mouse, the cat and the dog all immediately turn toward the direction of the sound. The dog barks, the cat twitches its tail and the mouse sniffs the air.


Programmatically, we can summarize this bizarre scenario as follows:


The mouse, cat and dog are 3 unique objects. They are not the same, but they have some characteristics that are the same. Together, they descend from a more generic superclass, which we will call a mammal. Mammals have ears, which allow them to process sound. The sound of the balloon popping causes each ‘object’ to process the sound in its own way: barking, tail-twitching and sniffing.


Imagine a number of Child classes were defined all with different names for a similar method (e.g. to display some attributes), it would mean having to remember all those different method names. This can be overcome by using the same name for the method in all the Child classes, which would only be called by the correct Type of object that was instantiated by the class.


In this example a Child class is derived from a Parent class, and both have the same named method of getValues() to display their object's attributes:

#include <iostream>
#include <string.h>
using namespace std;
class Motorbike { //Parent class
		char make[16], model[16] ;
		int speed, cc ;
		void setValues(char setMake[16], char setModel[16], int setSpeed, int setCc) { //setters
			strcpy (make, setMake ) ;
			strcpy( model, setModel );
			speed = setSpeed ;
			cc = setCc ;
		void getValues() { //getters
			cout << "Make: " << make << ", Model: " << model  ;
			cout << ", Speed: " << speed << "CC: " << cc ;
class Sports : public Motorbike { //Child class inheriting Motorbike class members
		char track[16] ;
		int position ;
		void setValues(char setMake[16], char setModel[16], int setSpeed, int setCc, char setTrack[16], 
				int setPos) {
			//using scope resolution :: operator for Motorbike class attributes
			Motorbike::setValues(setMake, setModel, setSpeed, setCc) ;
			strcpy (track, setTrack ) ;
			position = setPos ;
	void getValues() { //getters
		Motorbike::getValues() ;
		cout << ", Track: " << track << ", Position: " << position << endl ;
int main() {

	Motorbike street ; //instantiate a "Motorbike" object called "street"
	Sports racer ; //instantiate a "Sports" object called "racer"

	street.setValues("Honda", "Fireblade", 190, 1000) ; //define attributes
	racer.setValues("Ducati", "Panigale", 185, 1198, "Silverstone", 2); //define attributes

	//Polymorphism in action!!!
	//Using the same method to invoke different behaviour, according to the object type invoking it
	street.getValues() ;
	cout << endl ;
	racer.getValues() ;

	return 0;

The getValues() method is invoked against the specific object types on lines 48 and 50, upon which each invoke their own version of the getValues() method.



The 'eureka' moment came for me when I realised that it's the TYPE of object that controls the polymorphism. The TYPE of object being defined by the class that creates that object (& seeing that objects are abstract data types!), and therefore the object uses the methods applicable to it. Thus N objects could all have the same named method, but the calling object only executes it's own method - actually quite simple, once you get it !!


The association of a method call to the method definition


Two types: Compile time or Run time


Compile time

  • aka Early binding
  • Used for normal method calls
  • Performed if all information to invoke the method is available at the time of compilation
  • Faster since binding is completed at compilation


Run time

  • aka Late binding
  • Performed if information is missing at compile time, and only becomes available upon being run
  • Although slightly slower, enables response to events that occur during execution
  • Don't have to write code for contingencies that might occur during run time
  • Implemented with Virtual methods
    • Using a base reference to point to the type of object used by a method
      • Sometimes this is not known until run time, and binding cannot therefore be performed during compilation
      • Must wait until the program runs to bind the method call to the method


Also known as Compile Time Polymorphism


Allows the use of the same method name, as long as its signature is different.


The signature consists of the method name and a parameter list.



add(int a, int b)


add(double a, double b)


Therefore by providing different parameters (as in the number of parameters or types of parameters), we can use the same method name: this is known as method overloading.


Method overriding means having a different implementation of the same method in the inherited class. The Parent and the Child methods have the same signature, but different implementation, as per above.


A constructor is a special method that is invoked upon instantiation of an object and is used to provide initial values for the object being created. i.e. it sets the specified attributes to a known state.


It is always named exactly the same as the name of the class.


Has no return value.


Cannot be explicitly called.


Whenever an object is created, constructor will be called automatically, even if the programmer doesn't define a constructor the compiler will create an empty default constructor.


If a constructor has been defined, the compiler will not provide a default.


Do not include logical code in constructor, because it is only called once, when the object is instantiated


#include <iostream>
using namespace std;

class Coord {
		double ordX ;
		double ordY ;
		Coord() { //this is the constructor. Note the same name as the class
			ordX = 0 ; //initial value
			ordY = 0 ;
		void Results() {
			cout << "ordX: " << ordX << ", ordY: " << ordY << endl ;
int main() {
	Coord alan ; //declare an instance of the 'Coord' object called 'alan'
	alan.Results() ; //use the 'alan' object's 'Results()' method
	return 0;

The constructor is defined between lines 9 to 12


overloading the constructor allows different parameters to be supplied to use different constructors

#include <iostream>
using namespace std;

class Coord {
		double ordX ;
		double ordY ;
		Coord() { //this is the constructor. Note the same name as the class
			ordX = 0 ; //initial value
			ordY = 0 ;
		Coord(double overX, double overY){ //overloading the constructor
			ordX = overX ;
			ordY = overY ;
		void Results() {
			cout << "ordX: " << ordX << ", ordY: " << ordY << endl ;
int main() {
	Coord alan ; //declare an instance of the 'Coord' object called 'alan'
	alan.Results() ; //use the 'alan' object's 'Results()' method

	//declare another instance of the 'Coord' object called 'mary'
	Coord mary(17.623, 21.469) ; //overloading the constructor

	return 0;

In this example, an overloaded constructor has been defined between lines 13 to 16, that allow us to pass in initial values when defining the object on line 25.


A class destructor is called automatically when a class goes out of scope, and is used to clean up and free resources acquired by the object along its lifetime.


As with the Constructor, the Destructor uses the same name as the class but is prefixed with a ~ tilde.


Destructors take no parameters and have no return value.


This example show the destructor between lines 17 to 19, with an added "Object destroyed" message for info:

#include <iostream>
using namespace std;

class Coord {
		double ordX ;
		double ordY ;
		Coord() { //this is the constructor. Note the same name as the class
			ordX = 0 ; //initial value
			ordY = 0 ;
		Coord(double overX, double overY){ //overloading the constructor, with different types
			ordX = overX ;
			ordY = overY ;
		~Coord() { //showing that the destructor gets automatically called
			cout << "Object destroyed" << endl;
		void Results() {
			cout << "ordX: " << ordX << ", ordY: " << ordY << endl ;
int main() {
	Coord alan ; //declare an instance of the 'Coord' object called 'alan'
	alan.Results() ; //use the 'alan' object's 'Results()' method

	//declare another instance of the 'Coord' object called 'mary'
	Coord mary(17.623, 21.469) ; //overloading the constructor

	return 0;

Association, Composition, Aggregation



Drawing a line between objects implies there is some kind of interaction between those objects.


Could be as simple as one object is calling a method of another object.





Objects being made of other objects.


Known as the "Has-A" relationship:

  1. A motorbike has a engine
  2. A computer has a circuit board
  3. A house has rooms

In UML it is represented by an unfilled diamond head:


Shows an object contains N other objects.


Optionally, can have Multiplicity indicators to show the number of objects interacting, with * representing 0 to many


The dependency level indicated by the multiplicity indicators between objects is referred to as the Cardinality level.






Is also aggregation but more specifically implies ownership.


In UML, composition is show with a filled diamond connector between two objects.


One object is composed of other objects. e.g. a book is composed of many pages:



When an object is made up (is composed) of other objects, it means that when it is destroyed then so too are the contained objects. e.g. if the House object were deleted, then all the associated Rooms objects should be deleted too, and should not be expected to be shared with any other part of the application.


Whereas, in the aggregation example, if the car show room were deleted, the cars could be expected to live on their own.


Composition implies ownership, aggregation does not


I like to think of this like an Interface class, as opposed to a class's interface!  Could it perhaps be thought of as a class prototype?


Very similar to a class, but has no methods, just a list of method signatures:

interface doSomething {
	//method signatures
	void firstThing() ;
	void secondThing(int myVar) ;



By implementing an interface (i.e. using it), it's akin to signing a contract and promising to create those methods specified in the interface, within the class:

class Motorbike implements controlSpeed {
	public void brake(){
	public void acellerate(int speed) {
} ;



UML diagram. The <<Interface>> name is written between << guillemetes >>, and then lists the method signatures:




Then is implemented from a class, a dotted line with a blank arrow head is used:


Abstract Class

An abstract class is one that never gets instantiated.


It exists purely for the sake of being inherited, to provide shared behaviours


The complimentary term for a class that can be instantiated is a concrete class


Analysis & Design

  1. Get Requirements
  2. Describe the app
  3. Identify Main Objects
  4. Describe Interactions
  5. Create Class Diagram


Requirements Analysis


  • Functional
    • Features
    • Capabilities
  • Non-Func
    • Help
    • Legal
    • Performance
    • Support
    • Security
    • Functional
    • Usability
    • Reliability
    • Performance
    • Supportability

Expect Requirements to Change!


Expect something documented



Use Cases


User focus


Specify how user interacts with app


Use Case

  • Title What’s the goal? Keep it short
  • Actor Who wants it? Different people types or computers / data
  • Steps How do you achieve it? Single Paragraph, or Numbered List

Max of 1 or 2 days. Anything else is focussing on use cases, not the product!


Remember, requirements will change, stuff will have to be revisited / redone!




Can be user, application, system


ID Actors

  • External Systems / Organisations
  • Roles / Security Groups
  • Job Titles / Departments

Focus should be on the goal that the actor wants to achieve





  • Describes a goal that an actor can accomplish in a single encounter
  • Focus on the actors goal, not what they need to do to achieve that goal
  • Can have multiple scenarios
  • Go for simplicity
  • Use active voice
  • Omit needless words / detail
  • Not pseudo code / too much detail
  • Focus on intention
  • Use Case Prompts
    • Who does Sys admin?
    • Who Managers users & security?
    • What happens if system fails?
    • Is anyone looking at performance metrics / logs?


Use Case Diagrams


Diagram of several use cases, looked at the same time


To get the bigger picture


  • List the goals, the use cases – draw ellipse around each
  • Draw box around all the goals
  • List the actors – use stick figures
  • Draw line from actor to goals
  • Add any non-human systems, on the other side

  • Primary actors on the LHS. These are the actors that initiate
  • Secondary actors on the RHS. These actors take more of a reactive role
  • No order / sequence


  • Creating a Conceptual model of the app
  • Identifying the most essential items in the app
  • Review Analysis & Requirements
  • Show interactions
  • Focus on OO construction for the app
  • Should be quick
  • Only spend a few hours, at most!
  • Don’t worry about perfection / missing stuff


1 Identifying Objects / Classes


  • Pick out Nouns from Use Cases – candidate objects
  • Just make a list, don’t worry about missing any
  • Remove duplicates
  • Combine, where applicable
  • Might identify some attributes, which can be removed
  • Box the objects into a conceptual model

For example from an ecommerce system:


2 Identifying Class Relationships

  • Simply indicate associations with lines between boxes
  • Optionally add short note to describe the relationship
  • Can add multiplicity indicators
  • Doesn’t have to be perfect – this is a working / conceptual diagram
  • Conceptual object modelling


3 Identifying Class Responsibilities

  • Identifying the behaviour, which will eventually become methods
  • Review the use cases and identify the verbs / verb phrases
    • Identify who’s responsible
    • Remember that an object should always be responsible for itself


Verbs Actions
Verify items Display totals
Provide payment details Set payment details 

Set address details

Process sale Process order
Validate payment Validate payment
Confirm order Confirm order
Provide order number Get order number
Check order status Get status
Send order details email Create order confirmation email 

Send email

Beware of using SYSTEM with lots of behaviours!


Conceptual model should now start looking like class model



Class Responsibility Collaboration



Alternative method of modelling


  • Use Index cards
  • Use nouns to identify classes
  • Use verbs to identify responsibilities
  • Identify other classes interacting with, i.e. the collaborators
  • Place cards in a natural order (to you! there’s no right answer and it can always be refined).

Might see a gap for missing classes


If you find yourself running out of space on CRC card, then you've probably put too much in to that class


Creating Classes

Can now start building UML style class diagrams from previous modelling.


Class diagrams show the class name, attributes and behaviour, which then allows us to actually start writing the code.


  • Name classes in Singular
  • Attributes
    • Start using your own typical (programming) language identifiers
    • Common to see the data type of the attributes after the name
    • Can identify a default value, where necessary
  • Behaviours
    • getters / setters, etc
    • Common to see parentheses () containing any parameters
    • A return type is shown as the type required after a colon :
  • Visibility
    • - private to the class
    • + public

Sequence Diagrams

Behavioural / Dynamic diagram

Useful for describing lifetimes and interactions between objects
How objects change & communicate with each other
Does not describe the whole system, just one particular part of it
Useful for when something’s not understood


Important to note that these diagrams are not meant to show the whole system or all possible conditions to the Nth iteration
They offer an overview of the important aspects, not a model of the whole system

interaction between a few objects


  1. Start with N objects at top
    1. Named as per their instantiation
    2. To use class name, put it on the RHS of a colon
      1. instance name : class name
    3. If just class name, just : class name
  2. Insert vertical dotted time lines
  3. Then represent the messages between the objects
  4. Customer wants to checkout
  5. Cart creatNewOrder
  6. Cart adds different items addItem(item, quantity) using parameters
  7. Solid arrows with full head represent a regular message
  8. Dotted arrows with stick head represent a response itemTotal
  9. Don’t need to write return messages, only when they add value
  10. Solid boxes are called activation bxoes / method call boxes, represent processing being carried out in response to messages
  11. If message/response happens multiple times, they are surrounded by a frame, Loop, all items
  12. calcuateDiscount
  13. finaliseSale, leads to some processing in the order object, which send a total back to the customer
  14. Customer submitPayment
  15. Since we having nothing to take care of payment, we can show that the Order object is going to initiate a message that’s going to create a new Payment object
  16. Payment object sends back results (success or fail) then ends it’s lifeline as indicated with a large cross X
  17. results are sent back to Customer


This level of diagramming is useful for sitting down with a business user / customer, since they are not technical diagrams and are meant as a thinking tool


N sequence diags could be developed, but not required for all scenarios


They provide help with situations that aren’t clear, and might result in new classes being identified