HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex...

60
Glossary of Object-Oriented Concepts HIT2302 - Object-Oriented Programming Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 Abstract This document provides my understanding of all object-oriented concepts covered throughout the unit. It correlates with the concept-map developed over the semester and is designed to elaborate on topics featured in this concept-map. Please note that there is a bias to Objective-C and C ++ code in this glossary as they were my languages of choice this semester, although every effort has been made to include some examples in the other languages. 1

Transcript of HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex...

Page 1: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Glossary of Object-Oriented ConceptsHIT2302 - Object-Oriented Programming

Swinburne University of Technology

Alex Cummaudo1744070

November 26, 2013

Faculty of Information and Communication Technologies

HIT1301/HIT2080 Programming 1Laboratory 10: PointersThis laboratory introduces pointers and dynamic memory management. This will involve:

■ Writing source code for the programs including:■ Using pointers to read and write values■ Dynamically allocating memory

Resources

The following resources can help with this topic:■ Programming Arcana■ Introduction to Programming video podcasts on iTunesU

Submission

You need to submit print outs of the following material at the start of the 11th lecture.1. The new details added to your glossary2. Updated Hit List program using a dynamic array3. Any extension work you have completed.

Attach a lab coversheet to your submission with your details, your tutor's details, and a list of things you would like feedback on. Once you have discussed this with your tutor, and cor-rected any issues they raise with you, your work will signed off as complete.

Abstract

This document provides my understanding of all object-oriented concepts covered throughoutthe unit. It correlates with the concept-map developed over the semester and is designed toelaborate on topics featured in this concept-map. Please note that there is a bias to Objective-Cand C++ code in this glossary as they were my languages of choice this semester, although everyeffort has been made to include some examples in the other languages.

1

Page 2: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

CONTENTS Alex Cummaudo 1744070

Contents

1 Concept Map 4

2 Comparing Programming Paradigms 6

3 Objects 73.1 Why Have Objects? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.2 Abstraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3.2.1 Classification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83.2.2 Generalisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.2.3 Specialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.2.4 Making a Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3.3 Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123.3.1 Private Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.3.2 Public Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.3.3 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.4 Object Collaboration and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . 223.4.1 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233.4.2 Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

3.5 Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303.6 Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3.6.1 Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323.6.2 Inclusion (Overriding) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333.6.3 Coercion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343.6.4 Parametric or Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

3.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

4 Memory Handling 38

5 Communicating Object-Oriented Design 395.1 Unified Modelling Language (UML) . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

5.1.1 Class Diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395.1.2 Sequence Diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

6 Good Object-Oriented Design 426.1 Heuristics for Good Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

2

Page 3: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 CONTENTS

6.1.1 ‘Lazy’ Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426.1.2 ‘Anti-Social’ Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436.1.3 Judicious use of Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . 44

6.2 Model-View-Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446.3 Design Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

6.3.1 Decorator Design Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466.3.2 Command Design Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

7 Test Driven Development 50

8 GUIs and Event Handling 538.1 Event-Driven Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538.2 Toolkits for building UIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538.3 Observer Design Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

9 Exceptions 579.1 Try/Catch/Finally Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

3

Page 4: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

1 CONCEPT MAP Alex Cummaudo 1744070

1 Concept Map

The concept map developed over the semester is attached on the following page.Should this printed diagram be too small to read, feel free to read its digital online copy at

http://bit.ly/ConceptMapOOP—scan the QR code below to access—or alternatively, read thisPDF on the attached CD. As each section progresses, the concept map will be dissected intorelevant parts for better readability.

View the Concept Map:http://bit.ly/ConceptMapOOP

4

Page 5: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 1 CONCEPT MAP

Fig

ure

1.1:

Full

Con

cept

Map

5

Page 6: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

2 COMPARING PROGRAMMING PARADIGMS Alex Cummaudo 1744070

2 Comparing Programming Paradigms

Programs solve programs, using code to instruct the CPU and process the program’s solution. Theway we structure our code depends on a specific programming paradigm.

Traditionally, procedural programming paradigms used functional decomposition to break prob-lems down into smaller and smaller problems, in which functions and procedures solved each ofthese smaller problems to solve the larger one.

The problem with procedural programs is, once they grow too large, it becomes difficult tomaintain and manage their complexity. Structuring which function or procedure calls the otherand trying to visualise this process becomes too complicated in larger programs. This problemderives from data and functionality being distinct from each other; passing data from one part ofthe program down to another is quite tricky where there are thousands of procedures and functionsto work with.

The object-oriented paradigm solves this with a different approach to data and functionality.Both are encapsulated together into a single entity (an object); when objects communicate witheach other, methods are simply called from one object to another and no passing of data is requiredas a data has its own data self-contained.

This encapsulation concept is the key difference between the traditional and modern approach tosolving problems using programs, and is just one of four principles to the object-oriented approachto programming:

1. Abstraction

2. Encapsulation

3. Inheritance

4. Polymorphism

Using object-oriented programs to solve problems is ultimately most rewarding than proceduralprograms when a program grows to be far more complex; it is easier to visualise objects, whichcontain common data and functionality, working together than unrelated functions and proceduresworking together.

6

Page 7: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

3 Objects

Objects know and can do things.

The definition of an object is too abstract to define in just one or two sentences. Instead, thissection will discuss various features of what it is to be an object, defining each feature in detail. Atthe end of this section, a brief outline of all the major components that make up objects is defined.

Figure 3.1: Objects lie at the heart of all object-oriented programming.

3.1 Why Have Objects?

Use objects to break problems down, with each object defining its own roleand responsibility to help solve the problem.

While procedural programs used functional decomposition to achieve to better solve larger prob-lems, object-oriented programs break problems down into higher-level artefacts: objects. To solvethe problem, each object should have a particular role within the problem domain. Then, atrun-time, these objects are created to play out their roles.

Let’s look at the case of a game of Monopoly. If we look at Monopoly from an abstract point-of-view, we notice that certain entities exist should exist in order to play out a game:

7

Page 8: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

• A tile object would keep track of the players who are on it.

• A board object would maintain the tiles it contains.

• A player object would use the tiles to move around the board and play out the game.

If we look carefully at the examples above, we also see something in addition to just their role.We have also defined the responsibilities that the object has: a tile object is responsible forkeeping track of which player is on it, the board is responsible for knowing where its tiles are etc.

Thus, both roles and responsibilities define what an object is and what it needs to do in orderhelp solve the problem at hand, implementing this using both fields and methods.

3.2 Abstraction

A process of breaking problems down; we classify details of a common entitywithin the problem domain into a class and then generalise and specialisethem to make them applicable to more situations.

The use of abstraction lies behind what objects are and why they exist. When designing anobject-oriented program to solve a problem, objects should be abstracted from the real world. Aprogrammer should be able to extract details about a real-world object within the problem-domain,based on its appearance, purpose, responsibilities, actions and so on. In doing so, the systematicdevelopment of details about the object can be determined, achieved with the three steps:

1. Classification

2. Generalisation

3. Specialisation

3.2.1 Classification

The first step in the abstraction process is determining what is relevant for the problem-domainin terms of the real-world concept we want to work with. We need to be able to assign roles andresponsibilities from these concepts in order to abstract the game into an object-oriented program.This is known as the classification process.

Going back to our game of Monopoly, let’s look at what a board is. If we look deep enough, wecan see that the game board is just a bit of ink, printed on piece of cardboard. If we think even

8

Page 9: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

Figure 3.2: A board of Monopoly—while one abstraction may focus on minute details, our abstraction ofa game of Monopoly wouldn’t; thus there can be multiple abstractions for the same real-world object.

deeper still, we know that it is probably mulched wood, compressed together; in the end it’s alljust a series of atoms (see Figure 3.2).

But when we use abstraction to look at the Monopoly board as a game of Monopoly, we don’tsee ink, cardboard or atoms, but instead we form an abstract concept of a game of Monopoly—you know that from your abstract viewpoint that this is a game board (and more specifically werecognize that it’s laid out as a Monopoly board); we ignore the superfluous details because ourabstraction of a Monopoly game program does not focus on this; there are no roles for, say, thetype of ink used, because we’re not focusing on the physical board but what the board representsin terms of our problem-domain (a game of Monopoly). While we focus on the roles of tiles, playersand so on, another abstraction of a Monopoly program, such as a program to actually constructMonopoly boards, may have the opposite, where these minute, physical details of the board mayindeed be relevant. They would be included in that abstraction of Monopoly. Us, on the other-hand, forgo these physical details—we purposefully hide the physical details in order to highlightthe conceptual ones.

The next step after classifying roles is to establish the responsibilities of roles and relationshipsbetween different classifications. We discussed the responsibilities in Section 3.1, and we’ll discussour relationships in Section 3.4.

From this, we have realised what is relevant about our real-world concept relative to the problem-domain we want to solve. Thus the sub-process of classification allows us to:

• classify our roles into classes,

• can assign responsibilities to those classifications, and

• and associate relationships between these classifications.

9

Page 10: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

3.2.2 Generalisation

Figure 3.3: Generalising all the kinds ofMonopoly tiles into a ‘general’ Monopoly tile.

Once we have classified some classes, the next step isto generalise them; we go from concrete abstractionsto more general ones.

From our abstraction of the board, we’ll need tocreate some roles for properties, chance and commu-nity chest, jail, railway stations etc.

What is common about these? They are all dif-ferent kinds of tiles on the Monopoly board. We cangeneralise these classifications from their separate ab-stractions to the more general ‘tile’ abstraction. Fig-ure 3.3 helps to visualise this process; we go from morespecific classifications down to a more general classifi-cation. We can then use inheritance—see Section 3.4—to implement a hierarchy of objects that share commondata and functionality.

3.2.3 Specialisation

Figure 3.4: Specialising a ‘general’Monopoly tile into all the various kinds of

Monopoly tiles.

We can also go the other way; coming up with a clas-sification that is perhaps too general, but by no meansis wrong, can be drilled down to develop more classi-fications that extend the details of the more generalabstraction.

For example, if we came up with just a tile abstrac-tion first, and not the more specialised properties, jail,railway stations etc., we could have looked further intowhat kind of tiles may need to exist in the Monopolyabstraction. Then, using inheritance, we can imple-ment a hierarchy of objects collaborating together.

10

Page 11: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

3.2.4 Making a Class

Using these details, we have developed a classification of the various kinds of tiles, which we thenexpress by creating a tile class1.

A class outlines the classification, and may inherit from each other where they need to bespecialised or generalised. Think of a class as a ‘stamp’ in order to create instances of the object.We code our class to capture the specifications of the object we want to create, and then at run-time, we ask the class to make instances of our objects; the instance is allocated a space on theheap and is then told to point to that; see Section 3.3.3.

Therefore, by using the process of developing an instance from an abstract concept within theproblem domain can be solved as such:

1. We abstract the concept by developing classifications of the particular roles, then developresponsibilities and relationships between classifications

2. We can specialise and generalise these classifications as needed

3. Using these details, we produce classes representing these classification

4. We construct more objects using that class to create as many instances of the object as needed

Figure 3.5: Process of using abstraction to create instances of objects from their concepts.

1Classes too are also objects in themselves; if a program were to exist without class objects, then no class couldbe told to construct new instances of itself, since there would be no object of its kind to talk to at run-time.

11

Page 12: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

3.3 Encapsulation

Objects know things—their self-contained data—and can do things—actout their methods.

Viewing objects as just a set of functions and data is not a good approach to object-orientedprogramming. Instead, developers should conceptualise what an object should be: chiefly, whatdoes it know and what can it do? More generally, for it to know and do things, the it has to existin the first-place.

Figure 3.6: Encapsulation is divided into public and private details.

This simple strategy lies at the heart of encapsulation; whereas procedural programs considerthis as distinct—see Section 2—we combine both data (what it knows) and functionality (whatit does) as a whole in object-oriented programming, and this combination leads to an object. Byencapsulation, an object should exist in isolation; it needn’t rely on another object to perform itsown task with its own data (unless, of course it is collaborating—see Section 3.4—with anotherobject to fulfil its responsibilities).

However, the degree at which object display their methods and data may vary. We can identifyobjects as having public and private members, as separated by their interface with the restof the program, and their own internal implementation. An interface describes how objects caninteract with itself from the outside using its public information, and an implementation containsthe mechanisms for that object to work using its private information. Objective-C and C++ separatethese into header and implementation files.

Therefore, the visibility of a class can be summarised under the following scopes:

12

Page 13: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

Figure 3.7: Objects contain both their own data and functionality, which may or may not be kept inisolation from other objects

1. private, where members are available only to instances of the class and not to subclasses orusers,

2. protected, where members are accessible within the class and subclasses, but not to users,and

3. public, where members are accessible in the class, subclasses and users of the class.

3.3.1 Private Information

Private data and functionality—fields and private methods—can only beused and referenced within a class definition.

Private details of an object exist internally only; in the implementation of an object only. Privatedetails are used only by authors of the object so that these objects can play out their roles andresponsibilities. Two pieces of information can be kept private by an object:

1. Fields, or instance variables2—i.e., its data.

2. Private methods—i.e., its functionality.

Field values cannot be changed by users of the object; they are only manipulated by the methodsof the associated class. These are the concrete details which allow an object to exist on its ownaccord, regardless of if another object relies on it, and can only be used within the class definitionof an object.

Going back to our Monopoly example, we may find that some aspects of a tile may be keptprivate from other objects. For example, how a tile knows its whereabouts on the board, or theway the tile keeps track of its current players; it could be a data dictionary, or a collection—the

2Note the term instance variable; this means that the object holds this particular piece of data per instance thatthe object exists.

13

Page 14: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

client (user) of the object doesn’t need to know. This data is only used by the tile, for the tile’sown internal maintenance.

We can use the keywords private and protected within C++ , C# and Java to render the scopeof the information as private and protected. In Objective-C, we declare instance variables withinthe proceeding braces after the interface for a class is declared—see Listing 2. By convention, weuse an underscore to illustrate that these are fields and not properties.

3.3.2 Public Information

Public data and functionality—properties and public methods—can be usedand referenced outside a class definition.

What if another object or the program itself needs to access the private details as mentioned above?In such a case, we can make our private fields public by turning them into properties. As well asthis, we can make our methods public, allowing us to declare what the object can do, being calledfrom both other objects and the program.

To make a property in C++ , C# and Java we use the public keyword, and redeclare our fieldsas public, as well as their private counterpart. When we do this, we also need to declare our getter(or accessor) and setter (or mutator) methods; these methods, when called, simply get (return) orset the private field. By convention, the getter method is just the name of the property, while thesetter method is prefixed with ‘set’ and then the property name. Listing 1 emphasises this in C++ :

Listing 1: Declaring properties with their relative getters and setters in C++� �class Employee {

// Use the private keyword to declare// fields or private methods

private:int _daysWorked;float _payRate;

// Create the getter and setter methods for// the daysWorked property

public:

int daysWorked () { return _daysWorked; } // Returns daysWorkedvoid setDaysWorked(int val) { _daysWorked = val; } // Set daysWorked to val

};� �14

Page 15: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

In addition to properties that just return fields, we can make properties that return a calculationof fields:� �

public:float payPaid () { return _daysWorked * _payRate; }� �

In the example given immediately above, you may have noticed that we only provided thegetter method for payPaid, and not the setter method. This means that the property payPaid isa read-only property; it cannot be mutated, but only accessed.

Although creating properties in C++ , C# and Java are somewhat syntactically similar, Objective-C can automatically create your setting and getter methods for you by using the @synthesizekeyword. Let’s look how we can implement the examples above in Objective-C:

Listing 2: Properties in Objective-C� �@interface Employee {

// Declare instance variables inside// the braces of your interfaceint _daysWorked;float _payRate;

}

// Declare your properties outside the braces to make them public@property int daysWorked;@property float payPaid;

@end

@implementation Employee

// Use @synthesise to automatically create your getters and setters for Use@synthesize daysWorked = _daysWorked;

// But in the case of payPaid, we need to create our own getter since it is a// calculation of fields, not just a return of one-(float) payPaid { return _daysWorked * _payRate; }

@end� �Alternatively, if you’re not calculating a read-only property as in Listing 2, you can just use the

keyword readonly in your property declaration:

15

Page 16: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

� �@interface Employee {

// Other fields omitted...NSString* name;

}

// Declare a read−only property that is non−calculated with the readonly keyword@property (readonly) NSString* name;� �

3.3.3 Constructors

Constructors are important public methods which allow for the instantiationof an object.

On the topic of public methods, now is a good time to discuss how instances of objects are created.All objects must be initialised using special methods called constructors. A constructor initialisesfields and establishes the initial conditions required to manipulate a new object. In order toinstantiate an object, you must call its constructor method, storing the results of the constructorin a newly allocated variable for the instance of that object. Note here that we need to distinguisha separation between:

• Creating an object, which involves: allocating memory to a variable (the instance), assigninga name to that space (the instance’s name) and calling the constructor on that variable (i.e,defining which type of object that instance represents), and

• Initialising an instance, which involves just calling the constructor, without memory allocationto a new variable.

The constructor method is the most important aspect when defining a class, and thus it isusually placed at the very top of the class definition. By convention in C++ , C# and Java, theconstructor method is named after class it located in. Let’s look at a class definition of our employeeclass defined in Section 3.3 with a constructor method in C# :

Listing 3: The employee class, with its constructor at the very top of the method named after itself.� �class Employee {

// A new constructor for the Employee class

16

Page 17: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

public Employee (string n, int dW, float pR) {// Initialise the three private fields to the arguments given in our Employee// constructor._name = n;_daysWorked = dW;_payRate = pR;

}

// Declare properties of Employee (getters)public string name { return _name; }public int daysWorked { return _daysWorked; }public float payRate { return _payRate; }public float payPaid { return _daysWorked * _payRate; }

// Declare properties of Employee (setters)public void setDaysWorked(int val) { _daysWorked = val; }

// Declare private fieldsprivate string _name;private int _daysWorked;private float _payRate;

};� �We can then create the instance of an employee object by calling the constructor, and allocating

it some memory using the new keyword3.� �Employee fred = new Employee("Fred Smith", 5, 58.50);� �Objective-C has a slightly different method of providing constructors. Both the new keyword

and naming a constructor by its method name are omitted. Instead, the constructor is named init(initialise), returning an id-typed value (see Section 3.6 for more on Objective-C’s dynamically-typed nature) and usually conforms to the following syntax:

Listing 4: Constructors in Objective-C are slightly different to other languages. Note the pointer on thevariable.� �

@interface class {int _field;

}

3Note that C# and Java do not require a pointer reference on the instance’s variable, unlike C++ and Objective-C.This is because C# and Java use reference types for instance of objects, keeping pointer management hidden fromthe programmer. Internally, however, pointers are still used. This is further discussed in Section 4.

17

Page 18: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

// Declare a public interface to the class method.-(id) init;

@end

@implementation class

// The init method returns an id, a dynamically typed value-(id) initWithField:(int) f {

// 1) Self (this object) is equal to my parent object (super) initialised.self = [super init];

// 2) If my parent object was properly initialised, and therefore I don't point to nil?if (self != nil) {

// 3) Initialise instance variables using the arguments passed (if applicable)_field = f;

}

// 4) Return my freshly initialised self.return self;

}

@end

int main(){

// Allocate a `class' number of bytes memory to newClass.// newClass then points to this freshly allocated memory.class *newClass = [class alloc];

// Then initialise newClass so it has all its fields properly set.[newClass initWithField:12345];

return 0;}� �

Overloaded Constructors

Thanks to overloading polymorphism, which we discuss in 3.6.1, we can have multiple constructorsfor the same class, each of which can instantiate an object in different ways. By altering the typesignature of the constructor method, we can create different instances of objects with different

18

Page 19: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

meanings:

Listing 5: A set of overloaded constructors in C++� �using namespace std;

// Interface for Horseclass Horse {public:

// Define constructorsHorse (); // Default constructor (no args)Horse (string n); // Constructor with different type signature

// (string arg)Horse (int n); // Constructor with different type signature

// (int arg)Horse (string n1, int n2);// Constructor with different type signature

// (both string and int args)

// Define a name propertystring name();

private:string _name;

};

// Implementation for HorseHorse::Horse() { _name = ""; }Horse::Horse(string n) { _name = n; }Horse::Horse(int n) { _name = to_string(n); }Horse::Horse(string n1, int n2) { _name = n1 + " - " + to_string(n2); }

string Horse::name () { return _name; }

int main() {

// Create some Horses and initialise them using the various constructorsHorse *HorseWithNoName = new Horse();Horse *fred = new Horse("Fred");Horse *HorseNumber5 = new Horse(5);Horse *blackCaviar = new Horse("Caviar", 123);

// Print out some of the Horses namescout << "Horse 1: " << HorseWithNoName->name() << endl; // Out: Horse 1:cout << "Horse 2: " << fred ->name() << endl; // Out: Horse 2: Fredcout << "Horse 3: " << HorseNumber5 ->name() << endl; // Out: Horse 3: 5cout << "Horse 4: " << blackCaviar ->name() << endl; // Out: Horse 4: Caviar − 123

return 0;

19

Page 20: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

}� �Objective-C would handle this differently, without the use of overloading; this is because the set

of arguments are combined with the method name, thereby establishing an entirely new method,rather than the same method with a different type signature:

Listing 6: Objective-C allows us to modify the name of the method each time we add an argument, andtherefore we don’t have the same method name (and thus it is not using overloading.)� �

@interface horse {// Declare fieldsNSString* _name;

}

// Declare name property@property NSString* name;

// Declare constructors// Constructor Names:

-(id) init; // init-(id) initWithName:(NSString*) nameToGive; // initWithName-(id) initWithName:(int) number; // initWithName (different T/S)-(id) initWithName:(NSString*) nameToGive AndNumber:(int) number; // initWithNameAndNumber

@end

@implementation horse@synthesize horse = _horse;

-(id) init {self = [super init];

if (self != nil) {_name = "";

}return self;

}

// Constructor name has changed from init to initWithName-(id) initWithName:(NSString*) nameToGive {

self = [super init];

if (self != nil) {_name = nameToGive;

}

20

Page 21: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

return self;}

// Same constructor name as initWithName, different type signature-(id) initWithName:(int) number {

self = [super init];

if (self != nil) {_name = number;

}

return self;}

// Constructor name has changed from initWithName to initWithNameAndNumber-(id) initWithName:(NSString*) nameToGive AndNumber:(int) number {

self = [super init];

if (self != nil) {_name = first;NSString* second = [[NSString alloc] initWithFormat(@"%d"), number];[_name appendString:@" - "];[_name appendString:second];

}

return self;}

int main() {// Create some horses and initialise them using the various constructorshorse *horseWithNoName = [[horse alloc] init]horse *fred = [[horse alloc] initWithName:@"Fred"];horse *horseNumber5 = [[horse alloc] initWithName:5];horse *blackCaviar = [[horse alloc] initWithName:@"Caviar" AndNumber:123];

// Print out some of the horses namesNSLog(@"Horse 1: %@", horseWithNoName.name); // Outputs: Horse 1:NSLog(@"Horse 2: %@", fred.name); // Outputs: Horse 2: FredNSLog(@"Horse 3: %@", horseNumber5.name); // Outputs: Horse 3: 5NSLog(@"Horse 4: %@", blackCaviar.name); // Outputs: House 4: Caviar − 123

}� �

21

Page 22: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

3.4 Object Collaboration and Inheritance

Sometimes, objects are responsible for each other. As a result, they need to interact and collaboratewith each other in order to fulfil out their responsibilities and thus roles. Responsibility DrivenDesign lies at the heart of this; we design our object-oriented programs so that objects do the leastamount of work and ask each other to help them out to fulfil out their tasks. The program asksits objects to perform a service by sending it messages, and the objects themselves do this toother objects. These messages are simply requests to the object to perform its public methods.Remember: objects are lazy and they don’t want to do work which other objects (or data-structures)can do for them; as Budd (2001, p.11) phrases it:

Ask not what you can do to your data structures.Ask what your data structures can do for you.

Let’s go back to Monopoly. We could just make the board do all the work for us; the boardcould roll the dice, then move the players off from a tile to the set distance of the top value of thedice. However, this would make the board responsible for doing both the tile’s and player’s workfor them. Plus, the board is lazy.

Instead, we:

1. Ask the player to roll the dice.

2. Ask the player to ask the tile to take itself off itself.

3. Ask the player to move itself according to the dice’s value.

4. Ask the tile to land the player on itself once the player has moved the dice’s distance.

Figure 3.8: Responsibilities usually leads to collaboration between objects

22

Page 23: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

Relationship Explanation Verbal Relationship Illustration

Association

An object is associated withanother when it the state of

the latter depends on the theformer

A ‘has a’ relationship

Aggregation

Many objects are aggregatedwith one other object; whenthe singular object uses each

of its containing objects

A ‘part of’ relationship

Dependency

One object may use anotherobject whenever it needs to;once used, the using objectdoesn’t remember the used

object in future.

A ‘temporary use’ relationship

Table 3.1: Summary of the common relationships in object-oriented programs

As you can see, this textual description is very hard to read, and we instead communicate thisthrough Sequence Diagrams (see Section 5.1.2). There are four main types of collaboration, threeof which are summarised in Table 3.1. The fourth is explained in 3.4.1 below.

3.4.1 Inheritance

Child classes inherit data and functionality from a parent class, deriving froma common classification and collectively known as a family of classification.

Inheritance is the implementation of the specialisation and generalisation steps from the ab-straction process, Section 3.2. It is a special type of collaboration between classes; classes thatcollaborate with another class using inheritance are known as children or subclasses. They inheritboth the data and functionality as defined by their parent (or superclass) classes. Collectively,parents, children, grandchildren etc. are known as a family of classification (i.e., they all derivefrom some common classification).

Inheritance allows us to model an ‘is a’ relationship; looking back at the tile example in Sec-tion 3.2, we can see that a property would inherit the data and functionality of a the more generaltile. Thus, a property ‘is a’ tile, a railway station ‘is a’ tile, a jail ‘is a’ tile and so on.

23

Page 24: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

Figure 3.9: Inheritance concept map

What does this mean relative to data and functionality? If a tile contains fields such as name, ormethods such as landPlayer, then a property tile inherits these and makes it their own; Mayfair(an instance of a property object) includes ‘Mayfair’ as its name and it still contains the ‘landPlayer’functionality. However, it may choose to extend some of the attributes of its more general parentand make it more specialised; properties may add the field price, or method buy for example. Thisallows us to make the parent more specialised for the specific kind of object at hand.

As well as extending behaviour, we can modify behaviour within children. A child can changeits parents behaviour by overriding it; a ‘Community Chest’ may alter its parent’s landPlayermethod so that a player picks up a Community Chest card when they land. Ways in which to dothis may change in various languages:

Listing 7: Overriding a parent method in C++ using the virtual keyword.� �class Parent {public:

// Use virtual in the parent to allow for overriding in childvirtual void method();

};Parent::Parent method() { doThis(); }

24

Page 25: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

// Use a colon and the public keyword to inherit the class `Parent'class Child : public Parent {public:

// Reuse of virtual here is optional for the child.virtual void method();

};Child::Child method() { doThat(); }� �

Listing 8: Overriding a parent method in C# using the virtual and override keywords.� �class Parent {

// Use virtual in the parent to allow for overriding in childpublic virtual void method () { doThat(); }

}

// Use a colon to inherit the class `Parent'class Child : Parent {

// Use override in the child to override the parent's methodpublic override void method () { doThis(); }

}� �Listing 9: Overriding a parent method in Objective-C; no keywords are needed.� �

@interface Parent

// No keywords in definition-(void) method;

@end@implementation Parent

// No keywords in implementation-(void) method { [something doThis]; }

@end

// Use a colon to inherit the class `Parent'@interface Child : Parent

// Nothing needs to go in the interface interface was inherited from the parent

@end@implementation Child

25

Page 26: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

// No keywords in implementation; just override the method with different code-(void) method { [something doThat]; }

@end� �In C++ , C# and Java, a third scope modifier exists in addition to private and public:

protected. The protected scope means that anything within the class or children class canread that information. Here is an example of the protected scope in C++ :

Listing 10: Using the protected scope means the contents are accessible from the same class or children ofthat class only.� �

class Parent {public:

string foo() { return "Foo"; }

void test(){

cout << this->foo(); // Okay−−a public methodcout << this->bar(); // Okay−−a protected method (being read in same class)cout << this->baz(); // Okay−−a private method (being read in same class)

}

protected:string bar() { return "Bar"; }

private:string baz() { return "Baz"; }

};

class Child : public Parent {public:

void test(){

cout << this->foo(); // Okay−−a public parent methodcout << this->bar(); // Okay−−a protected parent method (being read by child)cout << this->baz(); // NOT okay−−a private method of the parent cannot be read by child

}

};� �26

Page 27: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

Abstract Classes

Inheritance comes in more forms than just generalisation and specialisation. Read Table 3.2 for adetailed description of all the forms of inheritance that exist. Subclassing for specification allows usto create abstract classes; these classes only define how to interface with its children, meaning thatall the methods declared in the class must be overridden by its children as there is no implementationin the parent (they are all abstract in the abstract class). As such, abstract classes cannot becreated into objects; their children can as the children guarantee that the abstract methods will beimplemented.

We can use the abstract keyword in C# and Java, and pure virtual methods in C++ (i.e., wherea virtual method is set to equal zero: virtual void method() = 0;). Objective-C does not useabstract methods since it is dynamically-typed—you can send any kind of message to any kind ofobject and it will compile, although there may be run-time errors where, at run-time, the receiverdoes not understand that message (causing a program crash). However, sending a message to anabstract class in a statically-typed language will cause a compile-time error.

Lastly, children that use inheritance may be known as subtypes, as opposed to just subclasses,given that the child follows the principle of substitution or inclusion polymorphism. This is de-scribed in detail within the Section 3.4.2.

Figure 3.10: Relationships between Abstract Classes and Interfaces.

27

Page 28: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

Form Description Example

SpecialisationA child becomes a more specialised

version of their parent.A Florist class is a specialised kind

of a Shopkeeper class.

GeneralisationA child overrides and extends its

parent’s behaviour

A Shape class can only be drawn in blackand white. We make a new child called

ColouredShape, which extends the behaviourof its parent to allow for colours to be added.

Specification(Abstract Classes)

The parent defines, but does notimplement, child behaviour.

A Sprite class defines the methods and data forfile image, physics for the sprite etc., but it is

never actually implemented. It’s children, suchas a Balloon and Dart, implement all the data

and functionality individually.

ConstructionA child makes use of parent

behaviour but is not asubtype of the parent.

A Set is a child of a List class. The Setisn’t a subtype of its parent—it is only using

List’s methods—and we wouldn’t useinclusion to substitute one for another—Set

is not necessarily a subtype of List.

ExtensionChild adds functionality that is

not related the parent, but to thechild only.

A Set class is the parent of a more specificStringSet class. The StringSet extends itsparent by adding a SearchStringsByPrefix

method, which only has meaning for the parentbut not the child.

LimitationChild has a more condensed version

of its parent’s behaviour.

A Deque class allows for adding data at eitherends; like a double-sided list. A Stack class

is a child of the the Deque class; it removes thedouble-sided functionality and only allows for

adding data to the end of the list.

Variance

Where two very familiar classes sharecode; one is arbitrarily set as the parent

only to reduce the need to duplicatecode—there is no actual hierarchy

between the two.

A Mouse and Tablet class would share the samefunctionality for controlling their input to a

computer. Mouse is arbitrarily chosen to be theparent of a Tablet simply to reduce the code.

CombinationA child class represents features of two

or more parent classes

A StudentTeacher class may inherit from boththe Student class and Teacher class; it can

therefore behave as both.

Table 3.2: A summary of various forms of inheritance, adapted from Budd (2001, pp.170-175).

28

Page 29: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

3.4.2 Interfaces

Defines functionality, but does not implement it, so that other objects thatuse it must implement the functionality.

What is important to note about inheritance is that one object can only inherit from one class.A class may have many children, but no child may have more than one parent. This one-to-manyrelationship is intentional in object-oriented languages due to a problem which can evolve if thisis approach were not followed. This is known as the diamond problem, the concept that adiamond-style tree of inheritance will cause conflicting data issues when a child wants to inheritfrom two families.

Say we have a class named X. X has a piece of data, d that is initialised with the value of zero. Xhas two children, A and B, both of which inherit the d field and change it to suit their own accord;for example, A sets d to 7 and B sets d to 3. Now, let’s assume that a fourth class Y wishes to inheritfrom both A and B; does Y inherit a d value of 7 from A or a d value of 3 from B? It is impossible todetermine, and it cannot inherit both since there is only one field of d. This is an example of thediamond problem, and why children cannot inherit from multiple classes.

Figure 3.11: Visual representation of thediamond problem.

To resolve this problem, the concept of an inter-face4.—not to be confused with a class interface (aheader file) in C++ or Objective-C—was developed. Aninterface is simply a set of defined methods—no fieldscan be defined in an interface, and the methods areonly defined and have absolutely no implementationin the interface declaration. The user of the interfacemust implement these methods however they wish, inorder to conform to the protocol that the interface hasdescribed.

Like abstract classes, protocols cannot be createdinto instances (since they are not classes) and have asimilar approach to specification inheritance, whereinthe parent—in this case, interface—defines but doesnot implement functionality. However, do not liken protocols to ‘parents’; inheritance only appliesto class-behaviour.

Essentially, we use protocols to find some link between a range of different, unrelated classes,or as a as a service provider to another class. For example a Card class, Shape class, and Student

4Objective-C uses the term protocol instead of interface

29

Page 30: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

class all use the Comparable interface—the Comparable interface has linked three unrelated classes.Inside the Comparable interface, we have a checkCompare method, which Card, Shape and Studentall use. Now, a new Sorter class can then get every object who is Comparable and perform theircheckCompare method, regardless of whether they are a Card, Shape or Student—in fact, theSorter has no idea of these three classes, but only knows that somewhere in the program existComparable classes. Thus, the Comparable interface acts as a service provider for Sorter.

3.5 Collections

Objects can be collectively stored and managed along with other objectsusing a collection.

Storing objects together for a common purpose is easily achievable using Collections. In somelanguages, Collections are objects in themselves, and we ask collections to add and manage otherobjects within themselves for us.

This is particularlly true for Objective-C’s NSMutableArray—the Mutable means that we canpush and pop objects to this array as many times as we like. The NSMutableArray accepts anykind of object, achievable due to Objective-C’s dynamically-typed nature.

In other languages, such as C++ , vectors can be used to store objects. However, since C++ is astatically typed language, generics polymorphism (see Section 3.6.4) is needed to specify what kindof object is contained within that collection—e.g. a vector of strings, a vector of Foo objects etc.

Commonly, we can use fast enumeration to iterate through our collections. Fast enumerationis a system that allows us to specify which class we want to iterate with within our collection. It’sfaster and easier to work with than a standard for loop.

Here’s an example of fast enumeration iteration in Java:� �for (Fruit f : fruits) // for all `Fruit' class variables in the `fruits' list, referred as `f'

groceries.add(f); // add the f'th fruit to the cart� �30

Page 31: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

Figure 3.12: Polymorphism concepts

3.6 Polymorphism

The same data can come in many forms, which can vary by the form of poly-morphism at hand: overloading, inclusion (overriding), coercion and para-metric.

Polymorphism is the concept where one piece of data can have many (poly) forms (morph), andis key to object-oriented programs. There are four types of polymorphism: parametric, coercion,inclusion and overloading polymorphism. Each make object-oriented programming rapidly easy,reliable, flexible and all with little overhead.

In dynamically-typed languages such as Objective-C, all variables are potentially polymorphic;the value stored by a variable can easily changed from one type to another as value types areattached to variables run-time. Thus polymorphic message sending is achieved without needing tocast of change variable types:� �

@interface Pumpkin : NSObject

-(void)favouriteVeg;

@end@implementation Pumpkin

-(void)favouriteVeg { NSLog(@"I'm a pumpkin!"); }

@end

@interface Banana : NSObject

31

Page 32: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

-(void)favouriteFruit;

@end@implementation Banana

-(void)favouriteFruit{ NSLog(@"I'm a banana!"); }

@end

int main(){

// Make a new variable with an id typeid variable;

// Variable is now a Pumpkinvariable = [[Pumpkin alloc] init];[variable favouriteVeg]; // Output: I'm a pumpkin!

// Variable is now an NSStringvariable = [NSString stringWithFormat:@"I'm a string!"];NSLog(@"%@",variable); // Output: I'm a string!

// Variable is now a Bananavariable = [[Banana alloc] init];[variable favouriteFruit]; // Output: I'm a banana!

return 0;

}� �In some statically-typed languages, such as C++ where the type of a variable is attached at

compile-time and cannot vary during run-time, polymorphic messaging is only achievable by usingpointers, overriding inheritance, and virtual methods, which is discussed in the following sections.

3.6.1 Overloading

Overloading is an ad-hoc form of polymorphism, which essentially allows for one identifier or opera-tor to have varying implementations. This can be achieved by altering a method’s type signature—the combination of the number, type and order of arguments in a method.

We saw overloaded methods in Section 3.3.3, where constructors had the same method namesbut varying type signatures. Likewise, we see this often with primitive operators, which automati-cally uses overloading to resolve type issues:� �32

Page 33: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

// A class exampleclass Class {public:

// Same method, different parameters (type signature)void overloadedMethod (int a);void overloadedMethod (string a);void overloadedMethod (int a, string a);

};

// More generic example11 + 5 // Two int parameters; same addition operator.0.50f + 6.60f // Two float parameters; same addition operator.� �

3.6.2 Inclusion (Overriding)

Overriding or inclusion polymorphism is a universal form of polymorphism, based upon the overrid-ing nature of a child in terms of its parent. In some ways, it is similar to overloading polymorphism,but occurs within a parent-child relationship context. Where inclusion is used on classes, the prin-ciple of substitution (or the Liskov Substitution Principle) should follow. Budd (2001, p.166)summaries this principle as:

Class B is a subclass of A... it should be possible to substitute instances of Class B for[that of] A in any situation with no observable effect.

An example of this is emphasised in Listings 11 and 12.

Listing 11: The principle of substitution (inclusion polymorphism) in C++� �// Declare some instances

Shape *s; // Parent (Shape−type variable points to no value)Rectangle *r = new Rectangle(); // Child of Shape (points to a rectangle value)Circle *c = new Circle(); // Child of Shape (points to a circle value)Triangle *t = new Triangle(); // Child of Shape (points to a triangle value)

// Reassign the shape−type variable to point to different value types:

s = r; // Shape now holds a rectangle value, but is still a shape−type variables = c; // Shape now holds a circle value, but is still a shape−type variables = t; // Shape now holds a triangle value, but is still a shape−type variable� �

33

Page 34: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

What is meant by ‘no observable effect’? Well, if we were to pass messages to Class B that areClass A messages, there would be no observable affect since Class B has overridden, and thus canstill accept, Class A style messages:

Listing 12: Overriding polymorphism in C++� �class Shape {public:

virtual void draw() { cout << "Drew a shape" << endl; }};

class Rectangle : public Shape {public:

// Override parent behaviourvirtual void draw() { cout << "Drew a rectangle" << endl; }

};

int main(){

Shape *s;Rectangle *r = new Rectangle();

// S is now holding a Shape values = new Shape();

s->draw(); // Output: Drew a shape

// S is now holding a Rectangle values = r;

s->draw(); // Output: Drew a rectangle

}� �At run-time, we change the value of the type stored by s from a Shape-type value to a

Rectangle-type value (i.e. s is equal to r); thus as the Rectangle class has the overridden methodfor Draw, then a Shape type variable can become, and respond to, Rectangle type values.

3.6.3 Coercion

Coercion is an ad-hoc form of polymorphism. It allows us to automatically map one type to anothertype, without the need for the principle of substitution to follow. A variable is assigned one type,but is assigned a value of another type, and to accommodate for this, we coerce the assignment

34

Page 35: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

value to match the variable type.We see this in primitive data types quite often:� �

// Floating point type variable stores an integer type value;// the integer is coerced to a float.float students = 30;

// Parent type variable holds a child type value;// the child type is coerced to a parent type.Parent *par = new Child();Shape *s = new Rectangle();� �The floating point variable, students, contains an integer value of 30. While the variable type

is a float, the value assigned to it is an int. Thus the integer 30 is automatically coerced froman integer to a float. The parent variable par is assigned a Child-class type value. The Child isautomatically coerced from a Child class value to a Parent class value.

3.6.4 Parametric or Generics

Parametric polymorphism is a universal form that whereby a type is specified as a parameter to ageneric or template (such as a collection). In the C++ example below, we see that two vectors storea collection of integers and strings; the type int and string are used as parametric polymorphismto further specify the type of vector being used.� �

Vector<int>; // A vector of integersVector<string>; // A vector of strings� �

3.7 Summary

1. Like functional decomposition in procedural programs, we use objects to break a problemdown.

2. Objects are derived from abstract concepts within the problem-domain.

3. We use the abstraction process to help achieve a class from these concepts, whereby:

(a) we ignore details about the concept that are not relevant to our problem,

(b) we classify objects into roles, what the object needs to accomplish in the program,assign responsibilities to those classifications (either to itself and/or other classes), and

35

Page 36: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

3 OBJECTS Alex Cummaudo 1744070

associate relationships between the classifications.

(c) we specialise a more general classification into smaller, more specific classifications,

(d) or we can generalise a group of specific classifications into one, broader classification.

4. We can use the class to create as many instances of the object as needed.

5. We encapsulate both data and functionality into the class, with any of a private, protectedor public scope.

(a) Privately scoped data (fields) and functionality (private methods) can only be accessedwithin the class it is defined in.

(b) Protectedly scoped data and functionality can be accessed within the class definitionand child class definitions.

(c) Publicly scoped data (properties, with setter and getter methods to set or get the fieldor data to access) and functionality (public methods) can be accessed anywhere in theprogram where the object is being used.

6. Constructors allow for the instantiation of private fields to initialise an instance of a class.

7. As some objects may be responsible for others, objects can collaborate with each other using:

(a) association relationships—where the first object ‘has a’ the second object,

(b) aggregation relationships—where the first object ‘is part of’ the second object,

(c) dependency relationships—where the first object ‘temporarily uses’ the second objectwhen it needs to,

(d) inheritance relationships—where one object inherits all the data and functionality fromthe second object (the first object ‘is a’ child of the second object).

8. We can use polymorphism to allow one piece of data to have many forms, and thus:

(a) an object can be declared as one type, but store the type of its child (subtyping),

(b) data can coerce its assignment value types so that it matches its declared type (coercion),

36

Page 37: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 3 OBJECTS

(c) methods can be overloaded so that the same method can have different meaning usingdifferent type signatures (overloading),

(d) a generic or template, such as a collection of objects, can be further specified by passinga type as a parameter to the generic (parametric).

37

Page 38: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

4 MEMORY HANDLING Alex Cummaudo 1744070

4 Memory Handling

In Sections 3.2 and 3.3.3, we mentioned that instances of objects are in fact pointers5, pointing toallocated memory on the heap specific for that instance. When we make a new instance, we allocateit some memory on the heap to create the instance, and use a constructor of a class’s method toinitialise that new instance.

Figure 4.1: Memory handling in object-oriented programs.

As this memory is allocated to the heap, as opposed to the program’s running stack, we areresponsible for releasing the memory we have allocated once we’re finished with our instances.There are two ways to achieve this:

1. manually, or

2. using garbage collection.

C++ and Objective-C do not use garbage collection; therefore objects need to be freed given thatno other object is still referencing that value (otherwise it may reference garbage if written over).This is made manageable by using reference counting, which is a “count of the number of pointersthat reference the object... when the count reaches zero, memory is released.” (Budd, 2001, p.111).Objective-C automatically does this for you using Automatic Reference Counting, while in C++ thiscannot automatically be done for you. In C++ , when an object is released, its destructor methodis called; this allows us to release any objects that the destructing object still references, thereby

5In C# and Java, objects use reference types, which removes the need for us to manually add pointer references;pointers are still implicitly in their internal representation.

38

Page 39: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 5 COMMUNICATING OBJECT-ORIENTED DESIGN

allowing those objects to no longer be referenced by this object. Destructors in C++ are signifiedwith a tilde prefixed in front of the class name (e.g. ˜Class() would be the destructor for the classClass, just as Class() is is constructor).

C# and Java use garbage collection, a way to “monitor manipulation of objects... which auto-matically recovers memory from objects that are no longer being used”(Budd, 2001, p.110). Thedownside to garbage collection is that it takes up extra resources, using a certain amount of exe-cution time to frequently sweep through the instances and check if they are being used elsewhere.However, programs do not easily run out memory, and (unlike manual freeing), it is impossible toreuse and re-free already freed objects, since if you were to use it, the object would not have beenswept and removed.

5 Communicating Object-Oriented Design

5.1 Unified Modelling Language (UML)

How can we communicate our roles and responsibilities classified when they were abstracted? UMLis “a standard way to write a system’s blueprints... for visualising, specifying, constructing anddocumenting [its] artefacts” (International Standards Organisation, 2005, ISO/IEC 19501:2005).Using UML, both object structure and object interaction can be described and visualised usingUML Class and Sequence Diagrams.

5.1.1 Class Diagrams

A class diagram describes the static structure of objects and how they are collectively structured.When reading and writing class diagrams, each class is surrounded by its own box, with varyinglines describing how that class interacts with others. The symbols in Table 5.1 should be followed.

5.1.2 Sequence Diagrams

Sequence diagrams describe the run-time interaction between objects. Each vertical block (anactivation period) describes one method that is currently being processed, with arrows indicatingthe interaction between each object during the sequence. Loops and conditionals are indicated withrectangles surrounding blocks, and the lifeline of the object is represented with a vertical dottedline.

Figure 5.2 displays a very simple sequence diagram for a simple calculator. We have threeclasses: Calc, Multi and PowerOf. We start at the instance c: c sends a message to the instancemp to multiply the values three and ten, highlighted with the solid line. The result is returned, as

39

Page 40: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

5 COMMUNICATING OBJECT-ORIENTED DESIGN Alex Cummaudo 1744070

Symbol Meaning Example

- Private data or functionality- _field: int- methodReturnsInt(): int

+ Public data or functionality+ property: int <<property>>+ methodWithParam(int): void

# Protected data or functionality # _data: intFilled Arrow Association relationship

Diamond Aggregation relationship

Filled DiamondAggregation relationship withownership over the second object(requires freeing owned object)

Dotted Line Dependency Relationship

Unfilled Arrow Inheritance Relationship

� interface � Interface declaration

Table 5.1: Common symbols in a UML Class Diagram

shown by the dotted line. Then, c sends a message to pwr to calculate 24 using its power method.In order for the PowerOf class to calculate this, it sends a message to mp to multiply three bythree. mp works out the answer, returns it to pwr, and pwr returns that result back to c.

40

Page 41: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 5 COMMUNICATING OBJECT-ORIENTED DESIGN

Figure 5.1: Relationships in communicating object-oriented design

Figure 5.2: A very simple UML sequence diagram.

41

Page 42: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

6 GOOD OBJECT-ORIENTED DESIGN Alex Cummaudo 1744070

6 Good Object-Oriented Design

Design quality of object-oriented programs are usually expressed in a number of different ways; wewant extensible programs that can flexibly add more components—programs that are robust andmodular. In terms of actually realising these qualities, it can be useful to have some sort of planthat describes how to go about achieving them.

Good object-oriented design has a manageable framework to structure the coupling and cohe-sion of classes. By coupling, we are referring to the relationships between classes and by cohesionwe refer to the relationships within classes (i.e., the degree of binding if elements inside the class).Thus, heuristics exist to help us develop a proper framework for good coupling and cohesion.

6.1 Heuristics for Good Design

There are three general strategies that exist to make well-designed object-oriented programs, re-gardless of the specific problem or product we want to create. As a good rule of thumb, good designincurs a balance between classes that have low coupling and high cohesion.

6.1.1 ‘Lazy’ Classes

Classes should be lazy—they should play a singular role only.

The level of cohesion a class has relates to how much the class does, and how well it performsit (i.e., the relationships and design within the class). Classes with high levels of cohesion shouldbe ‘lazy’, in that their roles are coherently substantiated to do distinct tasks and do those tasksvery well. We do this since it makes classes:

• easier to understand on their own accord,

• have methods relate easily and have lots in common with each other,

• reusable and modular.

This relates back to the idea of classification (Section 3.2.1); we want to ensure that each classis only in charge of one, coherent role within the solution. A rule of thumb is that if a class doesn’thave to perform a task, and it can go elsewhere, then it is best to delegate that functionalityelsewhere—even if that means the creation of another class or interface etc. Hence, every elementwithin a class should have some internal cohesion that helps fulfil the class’ role.

This also relates to encapsulation (Section 3.3), where if the object knows something, all activ-ities related with that data should stay with that object, and not go elsewhere. We try to allocate

42

Page 43: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 6 GOOD OBJECT-ORIENTED DESIGN

object functionality close to the data contained by the object. Thus, by reducing the visibility ofan object, we can easily characterise how the object is being used.

Hence, we keep data as private to the object as much as possible, have methods only to workwith that internal data and that data alone, and all other methods not directly relating with thatdata should be implemented in some other class.

6.1.2 ‘Anti-Social’ Classes

Classes should be anti-social—classes should collaborate only by means oftheir abstract concepts only.

Good design insists that classes shouldn’t be dependent on each other. The proportion ofdependency a class has on another is referred to how coupled the two classes are (i.e., the rela-tionships and design between the classes). Classes with high coupling mean that they dependent oneach-other very highly—we see this in classes that inherit from another; the child is closely coupledto its parent since it uses all of the data and functionality of its parents.

Good encapsulation should minimise the need to make private data public. Classes should nevergive access to information that isn’t relevant; other classes shouldn’t need to know how an objectstores it’s private data. A class is responsible for maintaining its fields, and no other class shouldhave to maintain its fields for it—think: it’s none of your business to know what private fields Ihave. We decouple as much of the two interacting objects as much as possible, thereby reducingthe amount of coupling.

In the event where it is necessary to use another object’s private details through a property, theusing object should not care how that other object does things. If access to a field is granted viaa property, use it but don’t question how it should work—the using object shouldn’t be delegatedany responsibility over the object it’s accessing if it is just accessing some information about it.Otherwise the accessible object loses some responsibility over itself, and when responsibility isdistributed over too many classes, it becomes harder for objects to be flexible and modular witheach other.

Thus, a reduction communication between classes helps achieve a reduction coupling classestogether.

43

Page 44: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

6 GOOD OBJECT-ORIENTED DESIGN Alex Cummaudo 1744070

Figure 6.1: An illustration of the Model-View-Controller design pattern.

6.1.3 Judicious use of Polymorphism

Derived classes should be compatible—inheritance and polymorphism shouldbe appropriately used between classes.

By using polymorphism judiciously, it should ensured that each child class is compatible withits parent, such that if it were used polymorphically, everything would work appropriately when achild is interchanged with its parent.

Think of the following example: is a bag of apples a bag of fruit? If we consider this in terms ofthe principle of substitution (Section 3.6.2), any child instance should be able to be treated as if itwere an instance of its parent. So, can the child instance (a bag of apples) be substituted with aninstance of its parent (a bag of fruit)? Of course not; if the bag of fruit contains apples, bananasand oranges, then it is no longer just a bag of apples, and thus polymorphism cannot be used inthis case.

6.2 Model-View-Controller

A common architectural model is the Model-View-Controller (MVC) architecture, usually imple-mented with an Observer Design Pattern (see Section 6.3.2). It is made up of the three componentsas in its name, and each components separates concerns for the program:

Model This is the abstract concept of the program, not tainted by other aspects about a computerprogram (e.g., how the user interfaces with the computer in order to use your abstract concept).

44

Page 45: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 6 GOOD OBJECT-ORIENTED DESIGN

For example, in terms of Monopoly, the model is the actual game of Monopoly and how it works;the actual concept of tiles, boards and players—regardless of how a player interfaces with the gamein order to actually play it. As it concerns itself with abstract concepts of the problem, it has nodependency whatsoever on the view or the controller.

View While the model is concerned with the abstract classifications of the problem-domain, theview is at the other extreme; it concerns itself with the way users interface with these abstractconcepts. Going back to Monopoly, the view receives information about Monopoly in order todisplay it to the user, but contains no knowledge of how a game of Monopoly actually works. Theview is entirely dependent on the model, and it is essentially the representation of the model to theuser. For example, a Monopoly game could be represented in a Graphical User Interface view, aCommand Line Interface view; the Monopoly game could be packaged up and sent over a network,thereby making it represented via a network view etc.

Controller We decouple both model and controller with an intermediary component called thecontroller. The user uses the controller to indirectly cause modifications to the model; these mod-ifications to the model are then propagated to the view—hence when a user interacts with theprogram, it may seem that they are modifying the view when they are instead modifying the modelvia the controller, which ultimately modifies the view.

Let’s look at this process, in reference to our Monopoly example (see Figure 6.2):

(A) The user makes interaction with the program via the controller.

(B) The controller propagates this interaction to make modifications to the model.

(C) The model propagates its changes back to the controller.

(D) The controller propagates these changes to each of the model’s associated views

(E) The user now sees these updated views which they indirectly modified.

6.3 Design Patterns

A design pattern is a way to emulate a proven solution to a new but similar problem so that allfuture sub-problems can be easily handled in the same way. They allow us not to ‘reinvent the wheel’by speeding up ways to find solutions to these sub-problems by aiding how we should structure ourclasses and relationships in a good, object-oriented manner—regardless of the problem-domain.

45

Page 46: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

6 GOOD OBJECT-ORIENTED DESIGN Alex Cummaudo 1744070

Figure 6.2: Model-View-Controller in the game of Monopoly.

6.3.1 Decorator Design Pattern

Figure 6.3: Visualisation of the wrapping in the sconesexample.

The decorator design pattern deals itselfwith adding new functionality to pre-existingobjects without the need to modify the exist-ing object. Rather than direct manipulationwith the class, we attach a new class to ex-tend the functionality of the existing class.This is done by wrapping the existing objectwith the decorator.

In order for this to occur, the decoratorneeds to satisfy the same requirements as itscontaining class, often passing much of theresponsibility to the containing class (albeitstill providing some new functionality). Wecan create decorators either by sub-classing

46

Page 47: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 6 GOOD OBJECT-ORIENTED DESIGN

both the decorator and contained class from a single parent, or by making both use the sameinterface to implement the same methods. Then, each decorator contains its containing class byusing it as a private method within its fields, being passed in a reference to the original object towrap around.

Decorators are a nice alternative to standard sub-classing (i.e., by making the decorator asubclass of the containing object) since functionality is added or removed by adding more or deletingwrappers around an object.

An example of this is illustrated in the example via Figure 6.3 and Listing 13. Here we have anabstract scone class, AbsScone, to which all other classes used are subclasses of. The first sconemade is then passed as a reference to the new sconeWithCream wrapped with the new Cream class.It is then further wrapped by a Jam class, with the sconeWithCream class being passed as a referenceto sconeWithCreamAndJam’s constructor.

Listing 13: Decorators in C++� �// Abstract scone class to inherit fromclass AbsScone {public:

// Abstract contents class using pure virtual methodvirtual string contents() = 0;

};

// Simple scone class (a subclass of AbsScone)class Scones : public AbsScone {public:

virtual string contents() { return " Scone"; }};

// Cream decorator class (a subclass of AbsScone)class Cream : public AbsScone {public:

// Constructor takes an existing scone to wrap aroundCream(AbsScone* scone) { _baseScone = scone; }

// New contentsvirtual string contents() { return _baseScone->contents() + " and Cream"; }

private:

// The contents of a cream decorator contains the// wrapped abstract scone classAbsScone* _baseScone;

47

Page 48: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

6 GOOD OBJECT-ORIENTED DESIGN Alex Cummaudo 1744070

};

// Jam decorator class (a subclass of AbsScone)class Jam : public AbsScone {public:

// Constructor takes an existing scone to wrap aroundJam(AbsScone* scone) { _baseScone = scone; }// New contentsvirtual string contents() { return _baseScone->contents() + " and Jam"; }

private:

// The contents of a jam decorator contains the// wrapped abstract scone classAbsScone* _baseScone;

};

int main() {

// Make a basic scone with nothing on that just// is a subclass of the basic AbsScone classScones *scone = new Scones();cout << "This scone has:" << scone->contents() << endl;

// Make a cream wrapper, passing in the original scone as// a reference to wrap aroundCream *sconeWithCream = new Cream(scone);cout << "This scone now has:" << sconeWithCream->contents() << endl;

// Make a jam wrapper, passing in the scone with cream as// a reference to wrap aroundJam *sconeWithCreamAndJam = new Jam(sconeWithCream);cout << "This scone now has:" << sconeWithCreamAndJam->contents() << endl;

return 0;

/∗

Output:This scone has: SconeThis scone now has: Scone and CreamThis scone now has: Scone and Cream and Jam

∗/

}� �48

Page 49: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 6 GOOD OBJECT-ORIENTED DESIGN

6.3.2 Command Design Pattern

The command design pattern makes parsing input text from users very easy, relatively comparedto procedural languages. In procedural languages, to usual way to go about this is to split thecommand up into an array of strings, comparing each substring against a large list of case statementsin a switch. Where there is a match, a separate function is then called.

The downside to this approach is that three things will always need to be updated wheneverthere is a new command:

• add the case statement for this new command in the switch

• add a new callback function elsewhere that will be executed in the case

• update the help command so that the description of this new command is added wheneverhelp is called

As you can see, this approach is clunky and error prone, since forgetting any one of these stepswill lead to gaps in the command approach.

In object-oriented languages, the command design pattern is solved by using objects; eachcommand is its own object and has its own self-contained description for the help and callbackor event handler function. Each new object is its own command; its role is to simply encapsulateall information needed to call a method at a later time. This eliminates the need for the casestatements and is a highly modular and compact approach to include commands in the program’scommand design.

Observer Design Pattern

See Section 8.3 for the close relationship between GUI interaction and this design pattern.

49

Page 50: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

7 TEST DRIVEN DEVELOPMENT Alex Cummaudo 1744070

7 Test Driven Development

Test Driven Development is focused around Unit Testing, a way to test each of the smallest possibleparts of your program. Each part of the program that can be tested, a unit, should have its ownunit test, which allows developers to ensure that the code written behind each unit functions asit was designed to. An object’s methods are usually units in object-oriented programs.

By using as many unit tests as possible, each part of the program’s functionality is tested againstthe designed (or expected) results and the actual results that the program gives. Unit tests Thethree steps behind each unit test are as follows:

1. Set up the test for the unit, making note of what is expected from the unit

2. Implement the unit itself

3. Perform the unit test

4. Check the actual results against the expected results

5. Revise the unit’s code when actual results do not match expected results

We always develop unit tests before we develop the code for the unit because, otherwise, thenature of the test may change to suit your code—developers want their code to work from theget-go, and so if they developed their tests after they’ve created their code, they will write teststhat will work, rather than writing code that will work. As such, developers may oversee certainpotential flaws of their code should they write unit tests after the unit was implemented—theyare biased so that their pre-written code will work for their unit tests, rather than having unit-tests written first and writing code afterwards. This essentially encourages developers to write theminimal amount of code to produce desired functionality.

IDEs (Integrated Development Environments) help speed up the unit testing process by provid-ing libraries which assist in automating each unit test. Some of these libraries are language specific—nUnit for C# , cppUnit in C++ , jUnit in Java and the Cocoa Unit Testing kit for Objective-C. Inorder to integrate unit testing into our programs, we can set up multiple targets for our program—one for the release program and another for the unit testing environment. By attaching a class toboth targets, we can then couple our predetermined unit tests to those classes and then test ourimplementation for those

Without an IDE’s unit test manager, unit testing becomes slow and inefficient; you essentiallytry to ‘break’ your release program by pushing it to its limits; writing bad code in, say, the mainbody of code to check whether your units will respond appropriately to bad code. There is no

50

Page 51: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 7 TEST DRIVEN DEVELOPMENT

distinct separation between your unit tests and your release program, and, as such, the chance ofleaving bad code in the release program is a possibility—leaving the potential to keep bugs in theprogram which the developer may forget about.

51

Page 52: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

7 TEST DRIVEN DEVELOPMENT Alex Cummaudo 1744070

Figure 7.1: Failed unit tests in the Xcode 5 IDE using Coca Unit Testing for Objective-C; the releasetarget is left untouched while the unit-testing target shows failed tests.

52

Page 53: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 8 GUIS AND EVENT HANDLING

8 GUIs and Event Handling

8.1 Event-Driven Programming

Figure 8.1: The world’s first commercial GUI OS onthe 1984 Mac introduced common interactive widgets

we’re all familiar with today.(Steinkamp and Kochanowski, 1999)

Every GUI is made of collections of wid-gets. A widget is any graphical element thatthe user can interact with: buttons, checkboxes, text fields, containers such as panelsand windows and so on. All of these com-ponents are their own object; a collection ofbutton widgets are simply instances of a but-ton class that is being drawn onto the screen.

Whenever a widget is activated, an eventis created by the widget to signal to the com-puter the widget has been activated. Anevent is created by user interaction, such abutton click, dragging an icon to the trashcan and so on, or by non-interactive occur-rences, such as a web page that finishes load-ing (the JavaScript load event).

An event listener observes and waits for an event to occur—each widget will maintain its owncollection of listeners and will take appropriate action whenever they are notified of an event bytheir widget.

To bind functionality to interactivity, the event handler method is attached to the event listenerso that programmatic features will react when interaction occurs. Consider the following exampletaken from the RPN calculator in Figure 8.2.

8.2 Toolkits for building UIs

To integrate events and widgets into object-oriented programs, you will need to consider creatingclasses for:

• A widget

• An event

• An event handler

• An event listener

53

Page 54: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

8 GUIS AND EVENT HANDLING Alex Cummaudo 1744070

Figure 8.2: A basic overview of the structure behind widgets, event handlers and listeners—the key rolesin event driven programming.

54

Page 55: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 8 GUIS AND EVENT HANDLING

Figure 8.3: Some of the CocoaFramework’s widgets located in its

Object Library.

Thankfully, various frameworks already exist which pro-vides most of the key functionality of widgets and events. ForObjective-C and Mac programming, the Cocoa framework pro-vides various widgets to use (see Figure 8.3), and the Xcode IDEprovides an Interface Builder to help design and implement thedesign and event handling of widgets (see Figure 8.4).

Without the Interface Builder, designing an interface for yourprogram would be very slow and tedious; you would have tomanually write the code to create each instance of each object,describing whereabouts they would be positioned on the screen,their appearance and so on. This is very hard to visualise, and itis easy to make errors in regards to positioning, event handlingand so on.

Instead, Xcode provides an easy solution for binding eventhandlers to widgets without ever needing to manage event lis-teners (the Cocoa framework handles most of the event handlingin the background). Simply control-click on a widget, and dragit onto its appropriate event handler method (see Figure 8.4).

8.3 Observer Design Pattern

The Observer design pattern is simply a dependency changestate pattern where if one object changes its state, each of itsdependent objects will be updated automatically. Communica-tion between the dependent objects and the subject are looselycoupled—communication between the two is kept to a minimal(see Section 6.1).

Apple’s Developer Library states that “the notification mech-anism of Cocoa implements one-to-many broadcast of messagesbased on the Observer pattern.” (Apple, Inc., 2012). By creat-ing instances of instances of the NSNotification class, simplenotifications can be broadcasted to change UI elements on the

screen when a specific event occurs within the program. This is an example of an intrinsic eventcaused not by user interaction, but by an event from functionality. Objects which receive externalinteraction such as user interaction can only react these notifications “only after the event hasoccurred” (Apple, Inc., 2012)—hence the event handler handling an event after it has been fired.

55

Page 56: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

8 GUIS AND EVENT HANDLING Alex Cummaudo 1744070

Figure 8.4: Binding the button number 9 to the event handler numberButtonClick!

56

Page 57: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 9 EXCEPTIONS

9 Exceptions

Exceptions simply are objects that encapsulate some form of error message. They are created toreport on any errors that a method may encounter. As such, they provide a system for alternatinghow a method may end—if a method does not work as intended (such as not including enoughoperands in the RPN Calculator from Week 11), then the method will create an exception object,forcing the method to end. Listing 14 illustrates this—the NSException class throws an exception,where there are less than two operands, to notify the program that user has not entered in enoughoperands for the calculation to continue (i.e., the validOperands method is called before anycalculation can occur to verify calculator input).

Listing 14: Throwing exceptions in Objective-C in the RPN Calculator program� �-(BOOL) validOperands{

// Where operands are less than twoif ([_operands count] < 2){

// Raise an exception, thereby causing the method to fail[NSException raise:@"InsufficientOperands"

format:@"Calculation requires at least 2 operands"];}// Otherwise, proceed...return YES;

}� �When dealing with exceptions, try to perform the code and catch any exceptions

Main

Method 1

Method 2

Method with ExcX

Object !Catch handles the exception

X @try { ... } @catch (NSException *e) { // cleanup ... }

Figure 9.1: An exception willcause the execution stack to

unwind, until it is handled or untilit causes the entire program to

terminate.

Exceptions, however, are not a graceful way to handle errorsin your program. Ideally, you should create your own error han-dling errors you will expect to occur—the RPN example shownabove demonstrates bad use of exceptions, whereby we know thata user may only enter just one operand, thereby causing an error.Exceptions should not be used for, in this case, validation, butinstead errors that you don’t expect your program to have—forthings that you don’t think of, not for known error conditions.

They should be used in exceptional circumstances where er-rors were unexpected; usually to handle errors of code that otherpeople have written (such as a framework). Rather than the er-ror bringing down the entire program, an exception can be raisedinstead, and then can be handled by a try/catch/finally block.

57

Page 58: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

9 EXCEPTIONS Alex Cummaudo 1744070

Exceptions are nasty and a slow way to handle errors; theyare essentially the last resort for error handling in your program. When an exception is thrown, itwill cause each method above the exception method to terminate, until it reaches the main programfunction. This process is known as ‘stack unwinding’; the execution stack unwinds itself by poppingoff each stack-frame, methods, until there are no more stack-frames to pop. If it is not handledanywhere along the path upwards to the last stack-frame (main), the program will terminate (seeFigure 9.1).

9.1 Try/Catch/Finally Blocks

The try/catch/finally blocks are a systematic way to deal with and handle exceptions.The try block attempts to run the code it contains, with the hope that any exceptions do not

occur. The try block should only be used for methods that may throw exceptions. If any of thetry block methods (or methods called by those methods) do throw an exception, the catch blockwill catch those exceptions, and clean up any mess they create. Lastly, the finally block will bethe very last block that is run, regardless of whether or not exceptions were raised in the try block.Listing 15 illustrates this.

Listing 15: Basic structure to Try/Catch/Finally blocks in Objective-C� �@try{

// Try to run the method `sayHello'[someClass sayHello];

}@catch (NSException *exceptionRaised){

// If any exceptions are thrown in sayHello, or methods called by sayHello// then catch those exceptions here and handle them nowNSLog(@"There was a nasty error!");

}@finally{

// Lastly, I'll say that I'm done after I've tried to run `sayHello'NSLog(@"I'm done now.");

}� �We can support multiple catch blocks for different types of exceptions thrown by comparing the

name of the exception raised—that is, comparing the raise argument on the NSException classto a fixed name. This is demonstrated in Listing 16.

58

Page 59: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

Alex Cummaudo 1744070 9 EXCEPTIONS

Listing 16: Having multiple catch blocks for handling exceptions with differing exception names (i.e. fordifferent exceptions raised).� �

@try{

// Try to run the method `sayHello'[someClass sayHello];

}@catch (NSException *exceptionRaised){

if (exceptionRaised.name == @"Goodbye"){

// Handling an exception who was created as a Goodbye exceptionNSLog(@"Couldn't say hello; you already said hello");

}}@catch (NSException *exceptionRaised){

// Handling an exception who was created as a Quiet exceptionif (exceptionRaised.name == @"Quiet"){

NSLog(@"Couldn't say hello; someClass is quiet today");}

}@catch (NSException *exceptionRaised){

// Handling an exception who was created as a Rude exceptionif (exceptionRaised.name == @"Rude"){

NSLog(@"Couldn't say hello; someClass is rude");}

}@finally{

// Lastly, I'll say that I'm done after I've tried to run `sayHello'NSLog(@"I'm done now.");

}� �

59

Page 60: HIT1301/HIT2080 Programming 1 November 26, 2013 in... · Swinburne University of Technology Alex Cummaudo 1744070 November 26, 2013 ... 7 Test Driven Development 50 ... responsibilities

REFERENCES Alex Cummaudo 1744070

References

Apple, Inc. Cocoa design patterns, 2012. URL http://developer.apple.com/library/mac/documentation/cocoa/conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW20. [Online; ac-cessed 12 Oct 2013].

T. Budd. An Introduction to Object-Oriented Programming. Addison-Wesley, 3rd edition, October2001. ISBN 9780201760316.

International Standards Organisation. Information technology—open distributed processing—unified modeling language (uml) version 1.4.2. 2005.

J. Steinkamp and G. Kochanowski. Mac desktop information, 1999. URL http://users.design.ucla.edu/˜cariesta/24VTWinter1999/html/body_mac_desktopinfo.html. [Online; accessed12 Oct 2013].

60