Objects in an Airport Domain

Learning Objectives

Pre-requisites

Lesson

In this lesson are going to implement the Airport system we modelled earlier in UML. This lesson is designed to introduce you to the idea of Object Oriented Programming (OOP). Objected-Oriented Programming languages such languages include C++, Java, TypeScript, Python and Scala use objects as the fundamental unit of coding. JavaScript is not a pure Object-Oriented Programming language however it does have support for classes.

Objects and Classes

Our Airport system has following classes in it:

detailed class diagram showing relationships between classes in the Airport domain

Here is how we create a Bag class and instantiate a new instance of the class (an object):-

class Bag {
    
    constructor(weight) {
        this.weight = weight
    }
}

const bag = new Bag(16)
class Bag {
    
    private weight: number;

    constructor(weight: number) {
        this.weight = weight;
    }
}

const bag = new Bag(16)
public class Bag {
    private int weight;

    public Bag(int weight) {
        this.weight = weight;
    }

    public int getWeight() {
        return weight;
    }
    // main method here just to illustrate how to create a Bag instance
    public static void main(String args[]) {
        Bag bag = new Bag(16);
    }
}

Each class has a special method known as a constructor which initialises the object with the values passed in as arguments.

The this keyword refers to the current instance of the class.

Note how in TypeScript and Java we have made the properties of the class private. This stops the properties being accessed directly by other classes, instead they have to be accessed via a public method. This allows us to change the internal implementation of a class (e.g. represent a bag weight in grams rather than kilograms) without affecting any calling classes. This is a key feature of OO languages known as encapsulation. Note that JavaScript does not support the private keyword.

Exception handling

Sometimes we need to inform the caller of a constructor that they must pass in a valid argument. In this case, we use the exception handling mechanism of our OO language to throw an exception if the argument is missing or invalid.

Let's imagine we want to ensure we only create bags with a valid weight - this protects other parts of our program trying to do calculations on an undefined or zero weight. The code below shows how we could use exception handling to avoid the construction of invalid bags.

class Bag {
    
    constructor(weight) {
        if (!weight) {
            throw new Error('bag must have a weight');
        }
        this.weight = weight
    }
}

class Bag {
    
    private weight: number;

    constructor(weight: number) {
        if (!weight) {
            throw new Error('bag must have a weight');
        }       
        this.weight = weight;
    }
}

public class Bag {
    private int weight;

     public Bag(int weight) throws Exception {
         if (weight<=0) {
             throw new Exception("bag must have a weight");
         }
         this.weight = weight;
     }

    public int getWeight() {
        return weight;
    }
}

We then use a try()/catch() block in the calling code to check whether an error has occurred, for example:

try {
    const bag = new Bag(16);
    // no error if we made it this far
} catch (Error e) {
    // handle error
}
try {
    const bag = new Bag(16);
    // no error if we made it this far
} catch (Error e) {
    // handle error
}
try {
    Bag bag = new Bag(16);
    // no error if we made it this far
} catch (Exception e) {
    // handle error
}

Bags belonging to a Passenger

Let's now focus on the Passenger class.

People often fly with a more than one bag. Our passengers should be able to carry multiple bags. What data structure would be appropriate for holding a list of bags?

To add a bag to a passenger we call a function/method on the relevant Passenger object. Here is an example where we add 2 bags to passenger 'bob':

const bob = new Passenger('Bob the Builder', "Passport123", "1A");
const bobsCabinBag = new Bag(9);
const bobsHullBag = new Bag(23);
bob.addBag(bobsCabinBag);
bob.addBag(bobsHullBag);

Think about how you would implement the addBag function/method.

Assignment

  1. Implement the Bag and Passenger classes. Include exception handling to ensure a Bag with a valid weight is constructed.

  2. Now we have Passengers with Bags, they are ready to board their flight! Complete the implementation of the remaining airport classes.

  3. Commit your code into Github and share the link with your coach for review

Assignment extension task

  1. If you are working in JavaScript, take a copy of your solution and convert it to use TypeScript. What differences do you notice? Note that the TypeScript files must use export = NameOfClass; rather than module.exports.
  2. Document your classes using the code documentation tool for your language e.g. JSDoc - for JS and TS or Javadoc comment structure and generate the HTML documentation. Why do you think this documentation could be useful?
  3. Commit your code and generated HTML documentation to your Git repository.