18.1 Adressable aspect

image_pdfimage_print

The fact that a number objects from different classes may be addressable is represented by defining a class Address:

class Address:
   country: var String 
   town: var String
   street: var String
   streetNo: var Integer
   print:
      country.print
      town.print
      street.print
      streetNo.print 
   change(newAddr: ref Address):
      country := newAddr.country
      town := newAddr.town
      street := newAddr.street
      streetNo := newAddr.streetNo

Address objects have the data-items country, town, street, and streetNo. The address may be changed by the change method, and it may be printed by the print method.

Customers being addressable is represented by Customer objects having an Address object:

class Customer:
   -"-
   addr: obj Address

The fact that a Customer object has an addr object as above implies that the attributes of the Address object are “kind of attributes of the Customer as well”, however, they are only indirect attributes as they have to be accessed through addr, like e.g.

aCustomer.addr.print

where aCustomer is a reference to a Customer object. The same would be the case inside the class Customer:

class Customer: Person
   -"-
   addr: obj Address
   ...
   addr.print
   ...

One could argue that for Address to be an aspect of Customer, the properties of Address should be directly accessible and not via the name addr of the part object. This would have been the case if Customer had been a subclass of Address, but that is obviously a wrong way to model this situation. A customer would typically be a type of e.g. person and it will have an address. From a modeling approach, a customer is not an address, but a customer has an address.

The addr object is a simple means to represent an aspect like address, as we use an already known mechanism of an intrinsic object (obj). However, it should be possible not only to apply a given aspect like Address to any class of object, but also to tailor the aspect to the class to which it is applied.

The print method of Address simply prints the address. If we also would like to print the name of the costumer, then we can not define addr simply as an Address object.

The usual way of making the print method so that it can be tailored in different Address aspects of different classes or objects is to define it as a virtual method:

class Address:
   -:-
   print:<
      inner(print)  -- whatever to print from the class/object that has
                    -- an Adress aspect
      country.print
      town.print
      street.print
      streetNo.print   

Instead of representing an Address aspect just by an Address object, the aspect is then rather represented by a singular intrinsic object with Address as a superclass and with an extension of the virtual print:

class Customer: Person
   -"-
   addr: obj Address
      print::
         name.print

Because print is extended in the context of Customer, i.e. nested in the description of Customer, the name data-item of Customer is visible and can therefore be printed in the extension of print.

Aspects may typically be applied to more than one class. Here it is applied to class Bank:

class Bank:
   name: var String
   addr: obj Address
      print::
         name.print

In this case print will print the name of the bank.

Suppose that we have a class BankCustomer that is subclass of Customer:

class BankCustomer: Customer
   bankName: var String  -- the name of the bank 
                         -- where the bank customer is a customer

Suppose that we still want to represent the Address as an aspect of Customer, and as an aspect of class BankCustomer, but still so that the aspect is tailorable in both Customer, in BankCustomer, and in further subclasses of BankCustomer. Then the above definition of addr will not do; we vill then have to define the class of addr by a virtual class AddrType:

class Customer: Person
   class AddrType:< Address
      print::<
         inner(print)
         name.print

   addr: obj AddrType  

class BankCustomer: Customer
   bankName: var String  
   class AddrType::<
      print::<
         inner(print)
         bankName.print

As the virtual class AddrType is defined defined in the context of Customer, the virtual print has access to the name of Customer, so name.print will print the name of the Customer. Note that the print method of AddrType is an extension of print in Address, but still virtual (::<) so that it can be further extended in the extension of AddrType in BankCustomer. This extension of AddrType is defined in the context of BankCustomer, and bankName is therefore visible in the further extension of print.