Skip to main content

Primer: Introduction to Object-Orientation

Firesand: End-to-End Security for your Business

Introduction

This article is one of a collection of primer articles, providing a basic introduction to various topics, for reference in other more in-depth articles. These primer articles are written as people come to security pages from various backgrounds, be it a software engineer who wants to understand an issue they need to fix (or prevent one from occurring in the first place) or a penetration tester with no background in software engineering, who wants to understand and know how to exploit a particular issue.

This primer is regarding Object Orientation.

Object Orientation

Object Orientation (OO) is a programming paradigm, a way of designing and developing software. It's emphasis is more on modelling the problem space than working closely with the computer. The OO paradigm itself is centred around, unsurprisingly, a concept called an object, and typically described as being built on of 3 main principles:

  1. Encapsulation,
  2. Inheritance, and
  3. Polymorphism.

In reality, there are many more elements and concepts (e.g. reusability, 'the open closed principle'; but these are all related to these three principles and the objects themselves). As such, we shall start with objects and these three principles.

Objects

Objects are a set of logically grouped data and behaviour. A common example is that of the car, which could have data such as: Brand, Model, Colour, Engine etc, and then related functionality such as: Start the Engine, Accelerate, Brake, Change Gear, Stop Engine, etc.

Objects themselves are really instances of a Class (Or we could say they are all members of a set). A Class is therefore often said to be the 'blueprint' for objects, and as such it is the Class that contains the code that defines a given object.

Following on from the above example, in an OO program we would have a Class that defines the Car, with its various pieces of data and functionality.

The following skeleton C#.NET code shows what this might look like:

public class Car
{
    // Data
    public string Brand;
    public string Model;
    public string Colour;

    // Functionality / Behaviour
    public void StartEngine()
    {
        // Code here.. 
    }
  
    public void StopEngine()
    {
        // Code here.. 
    }

    public void Accelerate()
    {
        // Code here.. 
    }
    
    public void ChangeGear()
    {
        // Code here.. 
    }
}

Objects, or Classes, can be composed of other objects, as you may have noticed, in the above sample, there is no data that refers to an Engine, we shall move onto this soon! 

But first, we shall discuss Universal Modelling Language (UML). UML is one method for capturing the design of an OO-based system. Two key UML types are: Static Structure and Sequence. Whilst Sequence Diagrams describe the behaviour of OO-based systems, Static Structure Diagrams describe the classes and their relationships. The following diagram demonstrates how to describe the above Class using UML: 

UML Static Structure / Class Diagram: Car

So, now we have that, how do we add an Engine to the system, or model? There are conceptually two different types of relationships like this, (1) Composition and (2) Aggregation. Composition is where one element is fundamentally made up of others, e.g. a relationship between a human and a brain, one cannot exist without the other. Whereas, aggregation describes less tightly bound relationships, e.g. where one element can exist without the other. In this instance, a Car can exist without an Engine (though, it may not drive so well), and an Engine can exist without a Car. 

The following diagram shows this relationship:

Car and Engine Aggregation: UML Static Structure Diagram

The empty diamond indicates an aggregation, whereas filled-in diamond would indicate composition. The number indicates just how many CarEngines are associated with a given Car.

Now that we have the beginnings of the understandings of what an object and a class is, as well as how this can be coded and represented diagrammatically, we shall move onto the three common principles of OO: Encapsulation, Inheritance, and Polymorphism.

For behaviour, whilst other programming paradigms use procedures and/or functions, OO uses methods. Practically speaking (though somewhat dependant upon the language), these are quite similar to procedures and functions.  A method either has a return type, or it does not, in which case the return type is indicated as void. A method without a return type is more similar to a procedure in some languages, whilst a method with a return type is more similar to a function in some languages. In the above code and UML diagrams, the methods are: StartEngine(), StopEngine(), Accelarate(), Brake(), and ChangeGear().

Finally, beyond UML it is worth noting that there are other methods for designing OO software, including the Z-Notation language, which is a mathematical way of defining software. This uses Pure Mathematics techniques to describe structures such as Classes and their functions (typically called Methods in OO). The Firesand Certified Secure Software Engineer training courses touch briefly on these methods.

Encapsulation

Encapsulation really is the idea of encapsulating a specific concept into a class or object, i.e. the combining of the related data and functionality. In addition, it also includes the notion that much of the inner workings and design of a class is hidden from its external users. This enables the engineers of a class to rework the internal aspects (perhaps for efficiency, or even security reasons) without affecting any other classes.

This is typically managed by having a public interface, i.e. as per the examples above, all the elements were marked as public. These are the elements that are usable by a calling class. There may, however, be a vast array of private variables and methods that enable the entire object to function properly.

It is generally a good idea to keep the most minimal public interface possible, this limits coupling between classes/objects and thus reduces the impact of change. 

Inheritance

Inheritance is a key component of OO, and one of the most overt ways that OO attempts to provide high levels of reusability. Inheritance allows us to specialise and generalise. Take, for example, the Car class that was designed above, functionality such as Accelerate(), as well as data such as Brand, Model, Colour, could all be abstracted away into a base class. This is because, these elements all apply to more than just cars, the apply to vehicles in general. 

Thus, we could place the common elements and logic into a base class. From which, we could then derive different types of vehicles, beyond car, that all share those attributes. For example, a Bike class. Further still, we could abstract away the Engine element into a another base class called MotorVehicle

The following UML diagram, expands upon the former, and presents such a model:

Vehicle UML Model

 

In this model, we now have to abstract base classes: Vehicle and MotorVehicle. Vehicle represents, generically, what it is to be a vehicle, data and behaviour (perhaps) common to all vehicles. We can say that this represents, mathematically, the total set of all possible vehicles. Whilst MotorVehicle represents, generally, what it is to be a MotorVehicle (i.e. a Vehicle that has an engine/motor!). 

Inheritance, in UML, is represented by the line with the hollow arrow. In code, this is often indicated using a colon or a keyword such as extends. The following C#.NET code presents the above model:

public abstract class Vehicle
{
    // Data
    public string Brand;
    public string Model;
    public string Colour;

    // Functionality / Behaviour
    public void Accelerate()
    {
        // Code here.. 
    }
    
    public void ChangeGear()
    {
        // Code here.. 
    }
}

public abstract class MotorVehicle : Vehicle
{
    // Functionality / Behaviour
    public void StartEngine()
    {
        // Code here.. 
    }
  
    public void StopEngine()
    {
        // Code here.. 
    }

    public MotorEngine Engine;
}

public class MotorEngine
{
    // Data
    public int NoOfCylinders;
    public string Manufacturer;
}

public class Car : MotorVehicle
{
    // Data
    public Seat[] Seats;   
}

public class Motorboat : MotorVehicle
{
    // Data
    public Rudder Rudder;
}

public class Bike : Vehicle
{
    // Data
    public Seat Seat;  
    public Handlebar Handlebar;
}

public class Handlebar
{
    // Code here
}

public class Rudder
{
    // Code here
}

public class Seat
{
    // Data
    public string Material;
    public string Colour;
}

Based on the code above, an instance of a Car would automatically gain all the properties and behaviour of the Car class, but also the MotorVehicle, and ultimately the Vehicle class. 

This ensures that the logic for Vehicle and MotorVehicle only need to be written once. The system, can now easily be extended to add in further Vehicle types. e.g. Unicycle, or any other type of vehicle, without having to rewrite all the code that had already been written for Vehicle or MotorVehicle.

Polymorphism

This is another key component of reusability within the OO world! This enables the development of highly reusable algorithms. It can be built using inheritance, but also other methods such as something termed 'interfaces' in some programming languages. 

We shall focus in on inheritance based polymorphism. Polymorphism literally means "many forms", and is a method by which - in OO - we can design a generic or common algorithm that works with a range of different objects. I.e. an algorithm can be written today, that continues to work for new programming types/classes tomorrow, next year, or the further in the future. Algorithms that allow for this are also said to support the Open-Closed Principle, where the algorithm is fixed (i.e. closed), yet is simultaneously open to change (i.e. open)!

To illustrate this, we can expand upon the prior vehicle-based example, let us suppose that there is a Garage class that can repair Cars, we can represent this using UML, as per the following:

 

Vehicle UML Model with Garage (no Polymorphism available)

 

Here we have now introduced a Garage class which offers a Repair method. This Method expects an instance of the Car class to be passed in. This is all well and good, but, ideally we do not want to have to write a different repair algorithm for every vehicle type, on the assumption that we can do the same thing (programmatically that is) for different types of vehicles.

As such, what OO allows us to do is to design algorithms that work on base classes, e.g. in this case it could be either MotorVehicle or Vehicle. Thus the Repair method could be written to support any and all MotorVehicles or any and all Vehicles. Simply by changing the type from Car to one of these. Obviously, the algorithm needs to truly work at a generic level!

What this then provides us, is the ability to write this Repair algorithm once, and have it function for all the existing Vehicle based types, and any future types that also inherit (or derive) from Vehicle.

So, we ultimately end-up with the following (nearly identical) design, with huge ramifications for reusability:

 

Vehicle UML Model (Polymorphism possible)

 

A key component of Polymorphism is that the one algorithm can ultimately behave differently based on the types passed in. Thus, to ensure this model does truly represent polymorphism, we will assume that the Repair method tests the vehicle, calling the Accelerate method on the provided vehicle, and we shall then assume that subclasses (Bike, Car, and Motorboat) have modified the behaviour of the Accelerate. Thus, when the Garage's Repair method executes the Accelerate method, the specific behaviour is different, without any change having been made to the Garage's Repair method itself.

Conclusion

OO allows software engineers and architects to design highly reusable code, in a very organised manner that is predominantly focussed on modelling the problem-space.

It is a powerful programming paradigm, and can be used to produce robust software, especially when combined with the concepts of asserts, pre-conditions, and post-conditions (which are covered in Firesand's Certified Secure Software Engineer training course. 

Note, this has been a whistle-stop tour of and introduction to Object Orientation, there are many concepts, techniques, etc not covered. But, the hope is that this has provides a better understanding of what Object Orientation is! As, it is useful for security professionals to understand what they are either securing, or trying to break!

Chris Blake

About the author

https://www.linkedin.com/in/chrisblake/

Chris Blake has over 20 years of experience in the information and cyber security field, and is a passionate and qualified Enterprise Security Architect and Privacy Professional who leads and delivers innovative solutions at Firesand Limited, a company he co-founded in 2016. His specialities include application security, enterprise security architecture, and privacy, with a strong track record of building and implementing ISO 27001 compliant and certified information security practices, application security programmes, and enterprise security architectures. He has a thirst for continual learning and a commitment to excellence, as demonstrated by his academic and professional credentials from prestigious institutions such as the University of Oxford, (ISC)², IAPP, SABSA, The Open Group, and ISACA.

Chris holds an MSc in Software and Systems Security at the University of Oxford, and an array of professional certifications: CISSP, ISSAP, CSSLP, CCSP, SSP.NET, SSP.JAVA, CISA, CISM, CIPP/E, CIPM, CIPT, FIP, SCF, TOGAF, CPSA, and CEH.

Chris' experience spans multiple sectors: Retail & eCommerce; Financial Services, Banking, & Payments; i-Gaming; Energy (Oil & Gas); Property Management & PropTech; and Data Science; as well as Defence. 

His areas of interests include: penetration testing; regulation & privacy, including the impact on society; access control in software; security automation in development; application of cryptography; security architecture; risk modelling & analysis; HTTP architecture & web security; IoT Security.

Cookie Notice

We use cookies to ensure that we give you the best experience on our website. Please confirm you are happy to continue.

Back to top