8 Object Associations part 1 Objects within Objects

8. Object Associations (part 1): Objects within Objects Mark Dixon, School of Computing SOFT 120 Page 1

Revision: User Defined Data Types • User Defined Data Types/Records – used to group data of different types type TAnimal. Rec = record Name: string; Species: string; Gender: Boolean; end; Mark Dixon, School of Computing SOFT 120 Page 2

Revision (continued) • It is necessary to store employee details, consisting of the following information: – Surname – Forenames – Salary • Provide the code to define a suitable record: type TEmployee = record Surname: string; Forenames: string; Salary: double; end; Mark Dixon, School of Computing SOFT 120 Page 3

Revision: Object Classes • Provide code to define an object class to do the same thing: type TEmployee = class Surname: string; Forenames: string; Salary: double; end; • Provide corresponding class diagram: TEmployee Surname: string Forenames: string Salary: double Mark Dixon, School of Computing SOFT 120 Page 4

Object Associations • In practice project will be made of – many object class – that interact with each other (are associated) • There are several types of association • One of the most often used is the ‘part of’ association, – where one object class forms part of another object class • A common example of this occurs where it is necessary to store multiple instances of a class Mark Dixon, School of Computing SOFT 120 Page 5

Container Class: Example • In the employees example, a class could be used to store details of a single employee • However, it is also necessary to store details of many employees • This could be done using a global array of employee objects: var Employees: array[1. . 10] of TEmployee; Mark Dixon, School of Computing SOFT 120 Page 6

Container Class: Example • However, it is better practice to place the group of employees into an employees object class (sometimes referred to as a container) that contains many employee objects (still implemented as an array) type TEmployees = class m. Items: array of TEmployee; m. Count: integer; end; • Note: the array has no range Mark Dixon, School of Computing SOFT 120 Page 7

Dynamic Arrays • All the arrays you have used so far have had their range explicitly defined in their definition: var Employees: array[1. . 10] of TEmployee; • This makes them static (i. e. their size cannot change) • This is restrictive as in real world problems the number of items being dealt with is frequently unknown during program design, or changes during program execution Mark Dixon, School of Computing SOFT 120 Page 8

Dynamic Arrays (continued) • Declaring an array with no range var m. Items: array of TEmployee; makes it dynamic (i. e. you can change its size as the program executes): • The Set. Length procedure changes the arrays size: Set. Length(m. Items, 5); this example would make the array 5 elements in size, indexed from 0 to 4 Mark Dixon, School of Computing SOFT 120 Page 9

Container Class: Example • The advantage of putting the details of all employees within a class of its own is that it allows relevant methods (functions and procedures) to be placed with it (encapsulated) as a single self contained unit • This can be placed in a separate unit file – To create a new unit select New from the File menu in Delphi and select the Unit Icon (all the way down the bottom) • This unit can then be used by other units (such as the main form unit) Mark Dixon, School of Computing SOFT 120 Page 10

Implementation: UEmployee unit UEmployee; interface type TEmployee = class Surname: string; Forenames: string; Salary: double; end; implementation end. Mark Dixon, School of Computing SOFT 120 Page 11

Implementation: UEmployees 1 unit UEmployees; interface uses UEmployee; type TEmployees = class m. Items: array of TEmployee; m. Count: integer; constructor Create(); destructor Destroy(); override; function Count(): integer; procedure Size(tmp. Num: integer); procedure Clear(); procedure Add(tmp. Surname: String; tmp. Forenames: String; tmp. Salary: double); end; Mark Dixon, School of Computing SOFT 120 Page 12

Implementation: UEmployees 2 procedure TEmployees. Size(tmp. Num: integer); var tmp. Ind: integer; begin Set. Length(m. Items, tmp. Num); for tmp. Ind : = m. Count to tmp. Num -1 do begin m. Items[tmp. Ind] : = TEmployee. Create(); end; m. Count : = tmp. Num; end; procedure TEmployees. Clear(); begin Size(0); end; Mark Dixon, School of Computing SOFT 120 Page 13

Implementation: UEmployees 3 function TEmployees. Count(): integer; begin Result : = m. Count; end; procedure TEmployees. Add(tmp. Surname: String; tmp. Forenames: String; tmp. Salary: double); var tmp. Item: integer; begin tmp. Item : = m. Count; Size(m. Count + 1); m. Items[tmp. Item]. Surname : = tmp. Surname; m. Items[tmp. Item]. Forenames : = tmp. Forenames; m. Items[tmp. Item]. Salary : = tmp. Salary; end; Mark Dixon, School of Computing SOFT 120 Page 14

Implementation: UEmployees 4 • Constructor – a special type of method that is used to create and initialise new objects: constructor TEmployees. Create(); begin Clear(); end; • Destructor – a special type of method that is used to destroy objects and release the memory allocated to them (mistakes in this often cause memory leaks) destructor TEmployees. Destroy(); begin Clear(); end; Mark Dixon, School of Computing SOFT 120 Page 15

Implementation: UMain 1 uses TEmployees; . . . implementation var Employees: TEmployees; var cur. Emp: integer; procedure Emp. Display(); begin with frm. Employees do begin lbl. Emp. Num. Caption : = Int. To. Str(cur. Emp); txt. Surname. Text : = Employees. m. Items[cur. Emp]. Surname; txt. Forenames. Text : = Employees. m. Items[cur. Emp]. Forenames; txt. Salary. Text : = Float. To. Str( Employees. m. Items[cur. Emp]. Salary); end; Mark Dixon, School of Computing SOFT 120 Page 16

Implementation: UMain 2 procedure Emp. Store(); begin with frm. Employees do begin Employees. m. Items[cur. Emp]. Surname : = txt. Surname. Text; Employees. m. Items[cur. Emp]. Forenames : = txt. Forenames. Text; Employees. m. Items[cur. Emp]. Salary : = Str. To. Float( txt. Salary. Text); end; Mark Dixon, School of Computing SOFT 120 Page 17

Implementation: UMain 3 procedure Tfrm. Employees. Form. Create(Sender: TObject); begin Employees : = TEmployees. Create(); Employees. Add('Smith', 'John', 11000); Employees. Size(3); cur. Emp : = 0; Emp. Display(); end; Mark Dixon, School of Computing SOFT 120 Page 18

Implementation: UMain 4 procedure Tfrm. Employees. cmd. Previous. Click(Sender: TObject); begin if cur. Emp > 0 then begin Emp. Store(); cur. Emp : = cur. Emp -1; Emp. Display(); end; procedure Tfrm. Employees. cmd. Next. Click(Sender: TObject); begin if cur. Emp < (Employees. Count - 1) then begin Emp. Store(); cur. Emp : = cur. Emp + 1; Emp. Display(); end; Mark Dixon, School of Computing SOFT 120 Page 19

Implementation: UMain 5 procedure Tfrm. Employees. cmd. Add. Click(Sender: TObject); begin Employees. Add('', 0); cur. Emp : = Employees. Count - 1; Emp. Display(); end; procedure Tfrm. Employees. cmd. Quit. Click(Sender: TObject); begin Application. Terminate(); end; procedure Tfrm. Employees. Form. Destroy(Sender: TObject); begin Employees. Destroy(); end; Mark Dixon, School of Computing SOFT 120 Page 20
- Slides: 20